Skip to content

Commit

Permalink
Logger: Add support for toggling sub logger name output for log events (
Browse files Browse the repository at this point in the history
thrasher-corp#407)

* Adds new optional log field. Adds padding to the fields to make it have a consistent output

* Line space and correct err message

* Removes padding code

* Moves `ShowLogSystemName` to advanced settings

* Uppers the names. Prevents pointer crash. Adds to config_example.json

* Adds test scenario for nil and true ShowLogSystemName

* buffer reset
  • Loading branch information
gloriousCode authored and thrasher- committed Jan 3, 2020
1 parent 98a277a commit f8ef6da
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 56 deletions.
4 changes: 4 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,10 @@ func (c *Config) CheckLoggerConfig() error {

f := func(f bool) *bool { return &f }(false)

if c.Logging.AdvancedSettings.ShowLogSystemName == nil {
c.Logging.AdvancedSettings.ShowLogSystemName = f
}

if c.Logging.LoggerFileConfig != nil {
if c.Logging.LoggerFileConfig.FileName == "" {
c.Logging.LoggerFileConfig.FileName = "log.txt"
Expand Down
10 changes: 8 additions & 2 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,7 @@ func TestCheckLoggerConfig(t *testing.T) {
c.Logging.LoggerFileConfig.FileName = ""
c.Logging.LoggerFileConfig.Rotate = nil
c.Logging.LoggerFileConfig.MaxSize = -1
c.Logging.AdvancedSettings.ShowLogSystemName = nil

err = c.CheckLoggerConfig()
if err != nil {
Expand All @@ -1740,11 +1741,16 @@ func TestCheckLoggerConfig(t *testing.T) {

if c.Logging.LoggerFileConfig.FileName != "log.txt" ||
c.Logging.LoggerFileConfig.Rotate == nil ||
c.Logging.LoggerFileConfig.MaxSize != 100 {
c.Logging.LoggerFileConfig.MaxSize != 100 ||
c.Logging.AdvancedSettings.ShowLogSystemName == nil ||
*c.Logging.AdvancedSettings.ShowLogSystemName {
t.Error("unexpected result")
}

c.LoadConfig(TestFile, true)
err = c.LoadConfig(TestFile, true)
if err != nil {
t.Errorf("Failed to load config: %v", err)
}
err = c.CheckLoggerConfig()
if err != nil {
t.Errorf("Failed to create logger with user settings: reason: %v", err)
Expand Down
1 change: 1 addition & 0 deletions config_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"maxsize": 250
},
"advancedSettings": {
"showLogSystemName": false,
"spacer": " | ",
"timeStampFormat": "02/01/2006 15:04:05",
"headers": {
Expand Down
19 changes: 12 additions & 7 deletions logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,28 @@ import (

func newLogger(c *Config) *Logger {
return &Logger{
Timestamp: c.AdvancedSettings.TimeStampFormat,
Spacer: c.AdvancedSettings.Spacer,
ErrorHeader: c.AdvancedSettings.Headers.Error,
InfoHeader: c.AdvancedSettings.Headers.Info,
WarnHeader: c.AdvancedSettings.Headers.Warn,
DebugHeader: c.AdvancedSettings.Headers.Debug,
Timestamp: c.AdvancedSettings.TimeStampFormat,
Spacer: c.AdvancedSettings.Spacer,
ErrorHeader: c.AdvancedSettings.Headers.Error,
InfoHeader: c.AdvancedSettings.Headers.Info,
WarnHeader: c.AdvancedSettings.Headers.Warn,
DebugHeader: c.AdvancedSettings.Headers.Debug,
ShowLogSystemName: *c.AdvancedSettings.ShowLogSystemName,
}
}

func (l *Logger) newLogEvent(data, header string, w io.Writer) error {
func (l *Logger) newLogEvent(data, header, slName string, w io.Writer) error {
if w == nil {
return errors.New("io.Writer not set")
}

e := eventPool.Get().(*LogEvent)
e.output = w
e.data = append(e.data, []byte(header)...)
if l.ShowLogSystemName {
e.data = append(e.data, l.Spacer...)
e.data = append(e.data, slName...)
}
e.data = append(e.data, l.Spacer...)
if l.Timestamp != "" {
e.data = time.Now().AppendFormat(e.data, l.Timestamp)
Expand Down
49 changes: 25 additions & 24 deletions logger/logger_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ func GenDefaultSettings() (log Config) {
MaxSize: 0,
},
AdvancedSettings: advancedSettings{
Spacer: " | ",
TimeStampFormat: timestampFormat,
ShowLogSystemName: f,
Spacer: " | ",
TimeStampFormat: timestampFormat,
Headers: headers{
Info: "[INFO]",
Warn: "[WARN]",
Expand Down Expand Up @@ -78,7 +79,7 @@ func configureSubLogger(logger, levels string, output io.Writer) error {
func SetupSubLoggers(s []SubLoggerConfig) {
for x := range s {
output := getWriters(&s[x])
err := configureSubLogger(s[x].Name, s[x].Level, output)
err := configureSubLogger(strings.ToUpper(s[x].Name), s[x].Level, output)
if err != nil {
continue
}
Expand Down Expand Up @@ -122,7 +123,7 @@ func splitLevel(level string) (l Levels) {

func registerNewSubLogger(logger string) *subLogger {
temp := subLogger{
name: logger,
name: strings.ToUpper(logger),
output: os.Stdout,
}

Expand All @@ -134,24 +135,24 @@ func registerNewSubLogger(logger string) *subLogger {

// register all loggers at package init()
func init() {
Global = registerNewSubLogger("log")

ConnectionMgr = registerNewSubLogger("connection")
CommunicationMgr = registerNewSubLogger("comms")
ConfigMgr = registerNewSubLogger("config")
DatabaseMgr = registerNewSubLogger("database")
OrderMgr = registerNewSubLogger("order")
PortfolioMgr = registerNewSubLogger("portfolio")
SyncMgr = registerNewSubLogger("sync")
TimeMgr = registerNewSubLogger("timekeeper")
WebsocketMgr = registerNewSubLogger("websocket")
EventMgr = registerNewSubLogger("event")
DispatchMgr = registerNewSubLogger("dispatch")

ExchangeSys = registerNewSubLogger("exchange")
GRPCSys = registerNewSubLogger("grpc")
RESTSys = registerNewSubLogger("rest")

Ticker = registerNewSubLogger("ticker")
OrderBook = registerNewSubLogger("orderbook")
Global = registerNewSubLogger("LOG")

ConnectionMgr = registerNewSubLogger("CONNECTION")
CommunicationMgr = registerNewSubLogger("COMMS")
ConfigMgr = registerNewSubLogger("CONFIG")
DatabaseMgr = registerNewSubLogger("DATABASE")
OrderMgr = registerNewSubLogger("ORDER")
PortfolioMgr = registerNewSubLogger("PORTFOLIO")
SyncMgr = registerNewSubLogger("SYNC")
TimeMgr = registerNewSubLogger("TIMEKEEPER")
WebsocketMgr = registerNewSubLogger("WEBSOCKET")
EventMgr = registerNewSubLogger("EVENT")
DispatchMgr = registerNewSubLogger("DISPATCH")

ExchangeSys = registerNewSubLogger("EXCHANGE")
GRPCSys = registerNewSubLogger("GRPC")
RESTSys = registerNewSubLogger("REST")

Ticker = registerNewSubLogger("TICKER")
OrderBook = registerNewSubLogger("ORDERBOOK")
}
44 changes: 33 additions & 11 deletions logger/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"io/ioutil"
"os"
"strings"
"testing"
)

Expand All @@ -20,8 +21,9 @@ func SetupTest() {
Level: "INFO|WARN|DEBUG|ERROR",
},
AdvancedSettings: advancedSettings{
Spacer: " | ",
TimeStampFormat: timestampFormat,
ShowLogSystemName: trueptr,
Spacer: " | ",
TimeStampFormat: timestampFormat,
Headers: headers{
Info: "[INFO]",
Warn: "[WARN]",
Expand All @@ -31,7 +33,7 @@ func SetupTest() {
},
SubLoggers: []SubLoggerConfig{
{
Name: "test",
Name: "TEST",
Level: "INFO|DEBUG|WARN|ERROR",
Output: "stdout",
}},
Expand Down Expand Up @@ -101,9 +103,9 @@ func TestRemoveWriter(t *testing.T) {
func TestLevel(t *testing.T) {
SetupTest()

_, err := Level("log")
_, err := Level("LOG")
if err != nil {
t.Errorf("Failed to get log %s levels skippin", err)
t.Errorf("Failed to get log %s levels skipping", err)
}

_, err = Level("totallyinvalidlogger")
Expand All @@ -115,7 +117,7 @@ func TestLevel(t *testing.T) {
func TestSetLevel(t *testing.T) {
SetupTest()

newLevel, err := SetLevel("log", "ERROR")
newLevel, err := SetLevel("LOG", "ERROR")
if err != nil {
t.Skipf("Failed to get log %s levels skipping", err)
}
Expand All @@ -135,7 +137,7 @@ func TestSetLevel(t *testing.T) {
}

func TestValidSubLogger(t *testing.T) {
b, logPtr := validSubLogger("log")
b, logPtr := validSubLogger("LOG")

if !b {
t.Skip("validSubLogger() should return found, pointer if valid logger found")
Expand Down Expand Up @@ -163,6 +165,9 @@ func TestConfigureSubLogger(t *testing.T) {
}) {
t.Error("configureSubLogger() incorrectly configure subLogger")
}
if Global.name != "LOG" {
t.Error("configureSubLogger() Failed to uppercase name")
}
}

func TestSplitLevel(t *testing.T) {
Expand Down Expand Up @@ -209,13 +214,13 @@ func BenchmarkInfoln(b *testing.B) {

func TestNewLogEvent(t *testing.T) {
w := &bytes.Buffer{}
logger.newLogEvent("out", "header", w)
logger.newLogEvent("out", "header", "SUBLOGGER", w)

if w.String() == "" {
t.Error("newLogEvent() failed expected output got empty string")
}

err := logger.newLogEvent("out", "header", nil)
err := logger.newLogEvent("out", "header", "SUBLOGGER", nil)
if err == nil {
t.Error("Error expected with output is set to nil")
}
Expand All @@ -225,7 +230,7 @@ func TestInfo(t *testing.T) {
w := &bytes.Buffer{}

tempSL := subLogger{
"testymctestalot",
"TESTYMCTESTALOT",
splitLevel("INFO|WARN|DEBUG|ERROR"),
w,
}
Expand All @@ -239,10 +244,27 @@ func TestInfo(t *testing.T) {
tempSL.output = nil
w.Reset()

SetLevel("testymctestalot", "INFO")
SetLevel("TESTYMCTESTALOT", "INFO")
Debug(&tempSL, "HelloHello")

if w.String() != "" {
t.Error("Expected output buffer to be empty but Debug wrote to output")
}
}

func TestSubLoggerName(t *testing.T) {
SetupTest()
w := &bytes.Buffer{}
registerNewSubLogger("sublogger")
logger.newLogEvent("out", "header", "SUBLOGGER", w)
if !strings.Contains(w.String(), "SUBLOGGER") {
t.Error("Expected SUBLOGGER in output")
}

logger.ShowLogSystemName = false
w.Reset()
logger.newLogEvent("out", "header", "SUBLOGGER", w)
if strings.Contains(w.String(), "SUBLOGGER") {
t.Error("Unexpected SUBLOGGER in output")
}
}
9 changes: 5 additions & 4 deletions logger/logger_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

const (
timestampFormat = " 02/01/2006 15:04:05 "
spacer = "|"
)

var (
Expand Down Expand Up @@ -41,9 +40,10 @@ type Config struct {
}

type advancedSettings struct {
Spacer string `json:"spacer"`
TimeStampFormat string `json:"timeStampFormat"`
Headers headers `json:"headers"`
ShowLogSystemName *bool `json:"showLogSystemName"`
Spacer string `json:"spacer"`
TimeStampFormat string `json:"timeStampFormat"`
Headers headers `json:"headers"`
}

type headers struct {
Expand All @@ -68,6 +68,7 @@ type loggerFileConfig struct {

// Logger each instance of logger settings
type Logger struct {
ShowLogSystemName bool
Timestamp string
InfoHeader, ErrorHeader, DebugHeader, WarnHeader string
Spacer string
Expand Down
16 changes: 8 additions & 8 deletions logger/loggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func Info(sl *subLogger, data string) {
return
}

displayError(logger.newLogEvent(data, logger.InfoHeader, sl.output))
displayError(logger.newLogEvent(data, logger.InfoHeader, sl.name, sl.output))
}

// Infoln takes a pointer subLogger struct and interface sends to newLogEvent
Expand All @@ -28,7 +28,7 @@ func Infoln(sl *subLogger, v ...interface{}) {
return
}

displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.InfoHeader, sl.output))
displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.InfoHeader, sl.name, sl.output))
}

// Infof takes a pointer subLogger struct, string & interface formats and sends to Info()
Expand All @@ -54,7 +54,7 @@ func Debug(sl *subLogger, data string) {
return
}

displayError(logger.newLogEvent(data, logger.DebugHeader, sl.output))
displayError(logger.newLogEvent(data, logger.DebugHeader, sl.name, sl.output))
}

// Debugln takes a pointer subLogger struct, string and interface sends to newLogEvent
Expand All @@ -67,7 +67,7 @@ func Debugln(sl *subLogger, v ...interface{}) {
return
}

displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.DebugHeader, sl.output))
displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.DebugHeader, sl.name, sl.output))
}

// Debugf takes a pointer subLogger struct, string & interface formats and sends to Info()
Expand All @@ -93,7 +93,7 @@ func Warn(sl *subLogger, data string) {
return
}

displayError(logger.newLogEvent(data, logger.WarnHeader, sl.output))
displayError(logger.newLogEvent(data, logger.WarnHeader, sl.name, sl.output))
}

// Warnln takes a pointer subLogger struct & interface formats and sends to newLogEvent()
Expand All @@ -106,7 +106,7 @@ func Warnln(sl *subLogger, v ...interface{}) {
return
}

displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.WarnHeader, sl.output))
displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.WarnHeader, sl.name, sl.output))
}

// Warnf takes a pointer subLogger struct, string & interface formats and sends to Warn()
Expand All @@ -132,7 +132,7 @@ func Error(sl *subLogger, data ...interface{}) {
return
}

displayError(logger.newLogEvent(fmt.Sprint(data...), logger.ErrorHeader, sl.output))
displayError(logger.newLogEvent(fmt.Sprint(data...), logger.ErrorHeader, sl.name, sl.output))
}

// Errorln takes a pointer subLogger struct, string & interface formats and sends to newLogEvent()
Expand All @@ -145,7 +145,7 @@ func Errorln(sl *subLogger, v ...interface{}) {
return
}

displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.ErrorHeader, sl.output))
displayError(logger.newLogEvent(fmt.Sprintln(v...), logger.ErrorHeader, sl.name, sl.output))
}

// Errorf takes a pointer subLogger struct, string & interface formats and sends to Debug()
Expand Down

0 comments on commit f8ef6da

Please sign in to comment.