From 44fabe31d89d799553b1b028dd53c6f0c0ab2235 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Fri, 24 May 2019 19:42:27 +0100 Subject: [PATCH 1/9] Make flags marshallable --- flags.go | 87 ++++++++++++++++++++++++++++++++++++++++++--------- flags_test.go | 46 +++++++++++++++++++++++++++ writer.go | 2 +- 3 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 flags_test.go diff --git a/flags.go b/flags.go index 928d42b..186f959 100644 --- a/flags.go +++ b/flags.go @@ -4,7 +4,13 @@ package log -import "strings" +import ( + "encoding/json" + "strings" +) + +// Flags represents the logging flags for a logger +type Flags int // These flags define which text to prefix to each log entry generated // by the Logger. Bits are or'ed together to control what's printed. @@ -16,16 +22,16 @@ import "strings" // The standard is: // 2009/01/23 01:23:23 ...a/logger/c/d.go:23:runtime.Caller() [I]: message const ( - Ldate = 1 << iota // the date in the local time zone: 2009/01/23 - Ltime // the time in the local time zone: 01:23:23 - Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. - Llongfile // full file name and line number: /a/logger/c/d.go:23 - Lshortfile // final file name element and line number: d.go:23. overrides Llongfile - Lfuncname // function name of the caller: runtime.Caller() - Lshortfuncname // last part of the function name - LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone - Llevelinitial // Initial character of the provided level in brackets eg. [I] for info - Llevel // Provided level in brackets [INFO] + Ldate Flags = 1 << iota // the date in the local time zone: 2009/01/23 + Ltime // the time in the local time zone: 01:23:23 + Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. + Llongfile // full file name and line number: /a/logger/c/d.go:23 + Lshortfile // final file name element and line number: d.go:23. overrides Llongfile + Lfuncname // function name of the caller: runtime.Caller() + Lshortfuncname // last part of the function name + LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone + Llevelinitial // Initial character of the provided level in brackets eg. [I] for info + Llevel // Provided level in brackets [INFO] // Last 20 characters of the filename Lmedfile = Lshortfile | Llongfile @@ -34,7 +40,7 @@ const ( LstdFlags = Ldate | Ltime | Lmedfile | Lshortfuncname | Llevelinitial ) -var flagFromString = map[string]int{ +var flagFromString = map[string]Flags{ "none": 0, "date": Ldate, "time": Ltime, @@ -50,10 +56,63 @@ var flagFromString = map[string]int{ "stdflags": LstdFlags, } +var flagOrder = []string{ + "date", + "time", + "microseconds", + "longfile", + "shortfile", + "funcname", + "shortfuncname", + "utc", + "levelinitial", + "level", +} + +// UnmarshalJSON converts a series of bytes to a flag +func (f *Flags) UnmarshalJSON(b []byte) error { + // OK first of all try an int + var i int + if err := json.Unmarshal(b, &i); err == nil { + *f = Flags(i) + return nil + } + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + *f = FlagsFromString(s) + return nil +} + +// MarshalJSON converts Flags to JSON +func (f Flags) MarshalJSON() ([]byte, error) { + stringFlags := []string{} + w := f + if w&LstdFlags == LstdFlags { + stringFlags = append(stringFlags, "stdflags") + w = w ^ LstdFlags + } + if w&Lmedfile == Lmedfile { + stringFlags = append(stringFlags, "medfile") + w = w ^ Lmedfile + } + for _, k := range flagOrder { + v := flagFromString[k] + if w&v == v && v != 0 { + stringFlags = append(stringFlags, k) + } + } + if len(stringFlags) == 0 { + stringFlags = append(stringFlags, "none") + } + return json.Marshal(strings.Join(stringFlags, ", ")) +} + // FlagsFromString takes a comma separated list of flags and returns // the flags for this string -func FlagsFromString(from string) int { - flags := 0 +func FlagsFromString(from string) Flags { + flags := Flags(0) for _, flag := range strings.Split(strings.ToLower(from), ",") { f, ok := flagFromString[strings.TrimSpace(flag)] if ok { diff --git a/flags_test.go b/flags_test.go new file mode 100644 index 0000000..0219574 --- /dev/null +++ b/flags_test.go @@ -0,0 +1,46 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package log + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +type testFlags struct { + Flags Flags `json:"flags"` +} + +func TestFlagsMarshalUnmarshalJSON(t *testing.T) { + flagsBytes, err := json.Marshal(testFlags{ + Flags: LstdFlags, + }) + assert.NoError(t, err) + assert.Equal(t, string(makeTestFlagsBytes("stdflags")), string(flagsBytes)) + + var testFlags testFlags + err = json.Unmarshal(makeTestFlagsBytes(`XAXAXA`), &testFlags) + assert.NoError(t, err) + assert.Equal(t, Flags(0), testFlags.Flags) + + err = json.Unmarshal([]byte(fmt.Sprintf(`{"flags":%d}`, LstdFlags)), &testFlags) + assert.NoError(t, err) + assert.Equal(t, LstdFlags, testFlags.Flags) + + flagString := "date, shortfile, levelinitial" + err = json.Unmarshal(makeTestFlagsBytes(flagString), &testFlags) + assert.NoError(t, err) + assert.Equal(t, FlagsFromString(flagString), testFlags.Flags) + flagsBytes, err = json.Marshal(testFlags) + assert.NoError(t, err) + assert.Equal(t, string(makeTestFlagsBytes(flagString)), string(flagsBytes)) +} + +func makeTestFlagsBytes(flagsString string) []byte { + return []byte(fmt.Sprintf(`{"flags":"%s"}`, flagsString)) +} diff --git a/writer.go b/writer.go index 22ef0b9..66a6d4d 100644 --- a/writer.go +++ b/writer.go @@ -27,7 +27,7 @@ type WriterLogger struct { Level Level `json:"level"` StacktraceLevel Level `json:"stacktraceLevel"` - Flags int `json:"flags"` + Flags Flags `json:"flags"` Prefix string `json:"prefix"` Colorize bool `json:"colorize"` Expression string `json:"expression"` -- 2.40.1 From 5c1f0fb448b71e845eee976e981f2809426c200d Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 26 May 2019 18:39:01 +0100 Subject: [PATCH 2/9] remove unnecessary map --- flags.go | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/flags.go b/flags.go index 186f959..56f06f4 100644 --- a/flags.go +++ b/flags.go @@ -40,22 +40,6 @@ const ( LstdFlags = Ldate | Ltime | Lmedfile | Lshortfuncname | Llevelinitial ) -var flagFromString = map[string]Flags{ - "none": 0, - "date": Ldate, - "time": Ltime, - "microseconds": Lmicroseconds, - "longfile": Llongfile, - "shortfile": Lshortfile, - "funcname": Lfuncname, - "shortfuncname": Lshortfuncname, - "utc": LUTC, - "levelinitial": Llevelinitial, - "level": Llevel, - "medfile": Lmedfile, - "stdflags": LstdFlags, -} - var flagOrder = []string{ "date", "time", @@ -97,8 +81,8 @@ func (f Flags) MarshalJSON() ([]byte, error) { stringFlags = append(stringFlags, "medfile") w = w ^ Lmedfile } - for _, k := range flagOrder { - v := flagFromString[k] + for i, k := range flagOrder { + v := Flags(1 << uint64(i)) if w&v == v && v != 0 { stringFlags = append(stringFlags, k) } @@ -114,9 +98,10 @@ func (f Flags) MarshalJSON() ([]byte, error) { func FlagsFromString(from string) Flags { flags := Flags(0) for _, flag := range strings.Split(strings.ToLower(from), ",") { - f, ok := flagFromString[strings.TrimSpace(flag)] - if ok { - flags = flags | f + for f, k := range flagOrder { + if k == strings.TrimSpace(flag) { + flags = flags | Flags(1< Date: Fri, 24 May 2019 21:57:16 +0100 Subject: [PATCH 3/9] Add autoconfig file --- log.go | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 128 insertions(+), 5 deletions(-) diff --git a/log.go b/log.go index 33e2cd1..47701f5 100644 --- a/log.go +++ b/log.go @@ -2,11 +2,22 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. +// Package log provides a more comprehensive logging system than that which go provides by default +// +// There are several methods for configuration including programmatically using the NewNamedLogger +// and NewLogger functions. There is also an init provided method to read a log configuration file +// provided as an argument to program: --log-config-file +// +// This configuration file is a JSON file of the form: +// {"DEFAULT_BUFFER_LEN":1000,"default":{"bufferLen":1000,"console":{"provider":"console","config":{"colorize":true, "flags":"stdflags","stacktraceLevel","error"}}} package log import ( + "encoding/json" "fmt" + "io/ioutil" "os" + "strings" ) var ( @@ -18,6 +29,15 @@ var ( hasDefaultLogger = false ) +// ErrBadConfig represent a bad configuration error +type ErrBadConfig struct { + message string +} + +func (e *ErrBadConfig) Error() string { + return fmt.Sprintf("Bad Configuration: %s", e.message) +} + // NewLogger create a logger for the default logger func NewLogger(bufLen int64, name, provider, config string) *Logger { if hasDefaultLogger { @@ -226,9 +246,112 @@ func (l *LoggerAsWriter) Log(msg string) { } } -func init() { - // create a default log to write to console - NewLogger(1000, "std", "console", fmt.Sprintf(`{"colorize":true, "flags":%d, "stacktraceLevel":"error"}`, - FlagsFromString("shortfile,shortfuncname,level,microseconds,date,shortfile"))) - hasDefaultLogger = true +type ourConfig struct { + name string + bufferLen int64 + subname string + provider string + config string +} + +func init() { + configFile := "" + nextArg := false + for _, arg := range os.Args { + if nextArg { + configFile = arg + break + } + if arg == "--log-config-file" { + nextArg = true + } else if strings.HasPrefix(arg, "--log-config-file=") { + configFile = strings.TrimPrefix(arg, "--log-config-file=") + } + } + if _, err := os.Lstat(configFile); err != nil { + configFile = "" + } + var err error + + if configFile != "" { + configs := []ourConfig{} + configMap := make(map[string]interface{}) + var bytes []byte + bytes, err = ioutil.ReadFile(configFile) + if err != nil { + goto NoConfig + } + err = json.Unmarshal(bytes, &configMap) + if err != nil { + goto NoConfig + } + defaultBufferLen, ok := configMap["DEFAULT_BUFFER_LEN"].(int64) + if !ok || defaultBufferLen == 0 { + defaultBufferLen = 1000 + } + for name, loggerconfigInterface := range configMap { + if name == "DEFAULT_BUFFER_LEN" { + continue + } + loggerconfig, ok := loggerconfigInterface.(map[string]interface{}) + if !ok { + err = &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s", name), + } + goto NoConfig + } + bufferLen, ok := loggerconfig["bufferLen"].(int64) + if !ok || bufferLen == 0 { + bufferLen = defaultBufferLen + } + for subname, subloggerconfigInterface := range loggerconfig { + subloggerconfig, ok := subloggerconfigInterface.(map[string]interface{}) + if !ok { + err = &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s:%s", name, subname), + } + goto NoConfig + } + provider, ok := subloggerconfig["provider"].(string) + if !ok { + err = &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s:%s", name, subname), + } + goto NoConfig + } + subconfigInterface, ok := subloggerconfig["config"] + + subconfig, err := json.Marshal(subconfigInterface) + if err != nil { + err = &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s:%s, provider %s: %v", name, subname, provider, err), + } + goto NoConfig + } + configs = append(configs, ourConfig{ + name: name, + subname: subname, + bufferLen: bufferLen, + provider: provider, + config: string(subconfig), + }) + } + } + if len(configs) == 0 { + err = &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration. No loggers."), + } + goto NoConfig + } + for _, c := range configs { + NewNamedLogger(c.name, c.bufferLen, c.subname, c.provider, c.config) + } + } +NoConfig: + // create a default log to write to console + NewLogger(1000, "std", "console", `{"colorize":true, "flags":"shortfile,shortfuncname,level,microseconds,date,shortfile", "stacktraceLevel":"error"}`) + hasDefaultLogger = true + if configFile != "" && err != nil { + Error("Error reading provided config file: %s Err: %v", configFile, err) + } } -- 2.40.1 From 707018fce239c05a692d8e1b42975b9256ba77fd Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sat, 25 May 2019 09:11:53 +0100 Subject: [PATCH 4/9] bufferlen should be in the sublogger --- log.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/log.go b/log.go index 47701f5..fadf654 100644 --- a/log.go +++ b/log.go @@ -192,7 +192,7 @@ func IsFatal() bool { return GetLevel() <= FATAL } -// Close closes all the loggers +// Close closes the default logger func Close() { NamedLoggers.Range(func(name string, logger *Logger) bool { NamedLoggers.Delete(name) @@ -300,10 +300,6 @@ func init() { } goto NoConfig } - bufferLen, ok := loggerconfig["bufferLen"].(int64) - if !ok || bufferLen == 0 { - bufferLen = defaultBufferLen - } for subname, subloggerconfigInterface := range loggerconfig { subloggerconfig, ok := subloggerconfigInterface.(map[string]interface{}) if !ok { @@ -312,6 +308,10 @@ func init() { } goto NoConfig } + bufferLen, ok := loggerconfig["bufferLen"].(int64) + if !ok || bufferLen == 0 { + bufferLen = defaultBufferLen + } provider, ok := subloggerconfig["provider"].(string) if !ok { err = &ErrBadConfig{ -- 2.40.1 From 0af49061e5d1fd4ea41f8a60ba971972934ea908 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sat, 25 May 2019 09:35:09 +0100 Subject: [PATCH 5/9] checked and working - if a little clunky --- log.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/log.go b/log.go index fadf654..76888aa 100644 --- a/log.go +++ b/log.go @@ -313,11 +313,8 @@ func init() { bufferLen = defaultBufferLen } provider, ok := subloggerconfig["provider"].(string) - if !ok { - err = &ErrBadConfig{ - message: fmt.Sprintf("Bad configuration for %s:%s", name, subname), - } - goto NoConfig + if !ok || provider == "" { + provider = subname } subconfigInterface, ok := subloggerconfig["config"] @@ -346,6 +343,7 @@ func init() { for _, c := range configs { NewNamedLogger(c.name, c.bufferLen, c.subname, c.provider, c.config) } + return } NoConfig: // create a default log to write to console -- 2.40.1 From 0dfb6d0c27bfd2318329fb3d425ae9db000ff98a Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sat, 25 May 2019 15:21:30 +0100 Subject: [PATCH 6/9] Make console logger colorize by default --- console.go | 10 ++++++++++ console_test.go | 4 ++-- log.go | 2 +- log_test.go | 12 ++++++------ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/console.go b/console.go index 6cfca8a..3e4a420 100644 --- a/console.go +++ b/console.go @@ -54,11 +54,21 @@ func (log *ConsoleLogger) Init(config string) error { if err != nil { return err } + configMap := map[string]interface{}{} + _ = json.Unmarshal([]byte(config), &configMap) + _, has := configMap["colorize"] + if log.Stderr { + if !has { + log.Colorize = CanColorStderr + } log.NewWriterLogger(&nopWriteCloser{ w: os.Stderr, }) } else { + if !has { + log.Colorize = CanColorStdout + } log.NewWriterLogger(log.out) } return nil diff --git a/console_test.go b/console_test.go index a028b5b..8f2b948 100644 --- a/console_test.go +++ b/console_test.go @@ -37,7 +37,7 @@ func TestConsoleLoggerMinimalConfig(t *testing.T) { cw := NewConsoleLogger() realCW := cw.(*ConsoleLogger) - cw.Init(fmt.Sprintf("{\"level\":\"%s\"}", level)) + cw.Init(fmt.Sprintf(`{"level":"%s","colorize":false}`, level)) nwc := realCW.out.(*nopWriteCloser) nwc.w = c @@ -72,7 +72,7 @@ func TestConsoleLogger(t *testing.T) { nwc := realCW.out.(*nopWriteCloser) nwc.w = c - cw.Init(fmt.Sprintf("{\"expression\":\"FILENAME\",\"prefix\":\"%s\",\"level\":\"%s\",\"flags\":%d}", prefix, level.String(), flags)) + cw.Init(fmt.Sprintf("{\"expression\":\"FILENAME\",\"prefix\":\"%s\",\"level\":\"%s\",\"flags\":%d,\"colorize\":false}", prefix, level.String(), flags)) assert.Equal(t, flags, realCW.Flags) assert.Equal(t, level, realCW.Level) diff --git a/log.go b/log.go index 76888aa..ae0c0d7 100644 --- a/log.go +++ b/log.go @@ -347,7 +347,7 @@ func init() { } NoConfig: // create a default log to write to console - NewLogger(1000, "std", "console", `{"colorize":true, "flags":"shortfile,shortfuncname,level,microseconds,date,shortfile", "stacktraceLevel":"error"}`) + NewLogger(1000, "std", "console", `{"flags":"shortfile,shortfuncname,level,microseconds,date,shortfile", "stacktraceLevel":"error"}`) hasDefaultLogger = true if configFile != "" && err != nil { Error("Error reading provided config file: %s Err: %v", configFile, err) diff --git a/log_test.go b/log_test.go index a4b9234..b388e3a 100644 --- a/log_test.go +++ b/log_test.go @@ -58,7 +58,7 @@ func baseConsoleTest(t *testing.T, logger *Logger) (chan []byte, chan bool) { func TestNewLoggerUnexported(t *testing.T) { level := INFO logger := newLogger("UNEXPORTED", 0) - err := logger.SetLogger("console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String())) + err := logger.SetLogger("console", "console", fmt.Sprintf(`{"level":"%s","colorize":false}`, level.String())) assert.NoError(t, err) out := logger.MultiChannelledLog.GetEventLogger("console") assert.NotEmpty(t, out) @@ -71,7 +71,7 @@ func TestNewLoggerUnexported(t *testing.T) { func TestNewLoggger(t *testing.T) { level := INFO - logger := NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String())) + logger := NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s","colorize":false}`, level.String())) assert.Equal(t, INFO, GetLevel()) assert.Equal(t, false, IsTrace()) @@ -103,7 +103,7 @@ func TestNewLoggger(t *testing.T) { func TestNewLogggerRecreate(t *testing.T) { level := INFO - NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String())) + NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s","colorize":false}`, level.String())) assert.Equal(t, INFO, GetLevel()) assert.Equal(t, false, IsTrace()) @@ -117,7 +117,7 @@ func TestNewLogggerRecreate(t *testing.T) { Log(0, INFO, format, args...) - NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String())) + NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s","colorize":false}`, level.String())) assert.Equal(t, INFO, GetLevel()) assert.Equal(t, false, IsTrace()) @@ -129,7 +129,7 @@ func TestNewLogggerRecreate(t *testing.T) { Log(0, INFO, format, args...) assert.Panics(t, func() { - NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s"`, level.String())) + NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s","colorize":false`, level.String())) }) go DelLogger("console") @@ -141,7 +141,7 @@ func TestNewLogggerRecreate(t *testing.T) { func TestNewNamedLogger(t *testing.T) { level := INFO - err := NewNamedLogger("test", 0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String())) + err := NewNamedLogger("test", 0, "console", "console", fmt.Sprintf(`{"level":"%s","colorize":false}`, level.String())) assert.NoError(t, err) logger := NamedLoggers.LoadOnly("test") assert.Equal(t, level, logger.GetLevel()) -- 2.40.1 From 390b62ff4abbee22f14532f57f5f16c12b33a8c0 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 28 May 2019 09:07:41 +0100 Subject: [PATCH 7/9] move configuration out into a separate file --- configuration.go | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ log.go | 86 +++-------------------------------------- 2 files changed, 104 insertions(+), 81 deletions(-) create mode 100644 configuration.go diff --git a/configuration.go b/configuration.go new file mode 100644 index 0000000..9f42f9f --- /dev/null +++ b/configuration.go @@ -0,0 +1,99 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package log + +import ( + "encoding/json" + "fmt" + "io/ioutil" +) + +type ourConfig struct { + name string + bufferLen int64 + subname string + provider string + config string +} + +// ConfigureFromFile configures logging from a provided file +func ConfigureFromFile(filename string) error { + bytes, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + return ConfigureFromBytes(bytes) +} + +// ConfigureFromBytes configures logging from provided []byte +func ConfigureFromBytes(config []byte) error { + configs := []ourConfig{} + configMap := make(map[string]interface{}) + + err := json.Unmarshal(config, &configMap) + if err != nil { + return err + } + + defaultBufferLen, ok := configMap["DEFAULT_BUFFER_LEN"].(int64) + if !ok || defaultBufferLen == 0 { + defaultBufferLen = 1000 + } + + for name, loggerconfigInterface := range configMap { + if name == "DEFAULT_BUFFER_LEN" { + continue + } + loggerconfig, ok := loggerconfigInterface.(map[string]interface{}) + if !ok { + return &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s", name), + } + } + for subname, subloggerconfigInterface := range loggerconfig { + subloggerconfig, ok := subloggerconfigInterface.(map[string]interface{}) + if !ok { + return &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s:%s", name, subname), + } + } + bufferLen, ok := loggerconfig["bufferLen"].(int64) + if !ok || bufferLen == 0 { + bufferLen = defaultBufferLen + } + provider, ok := subloggerconfig["provider"].(string) + if !ok || provider == "" { + provider = subname + } + subconfigInterface, ok := subloggerconfig["config"] + + subconfig, err := json.Marshal(subconfigInterface) + if err != nil { + return &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration for %s:%s, provider %s: %v", name, subname, provider, err), + } + } + configs = append(configs, ourConfig{ + name: name, + subname: subname, + bufferLen: bufferLen, + provider: provider, + config: string(subconfig), + }) + } + } + if len(configs) == 0 { + return &ErrBadConfig{ + message: fmt.Sprintf("Bad configuration. No loggers."), + } + } + for _, c := range configs { + err = NewNamedLogger(c.name, c.bufferLen, c.subname, c.provider, c.config) + if err != nil { + return err + } + } + return nil +} diff --git a/log.go b/log.go index ae0c0d7..98976cc 100644 --- a/log.go +++ b/log.go @@ -13,9 +13,7 @@ package log import ( - "encoding/json" "fmt" - "io/ioutil" "os" "strings" ) @@ -246,14 +244,6 @@ func (l *LoggerAsWriter) Log(msg string) { } } -type ourConfig struct { - name string - bufferLen int64 - subname string - provider string - config string -} - func init() { configFile := "" nextArg := false @@ -274,82 +264,16 @@ func init() { var err error if configFile != "" { - configs := []ourConfig{} - configMap := make(map[string]interface{}) - var bytes []byte - bytes, err = ioutil.ReadFile(configFile) - if err != nil { - goto NoConfig + err = ConfigureFromFile(configFile) + if err == nil { + return } - err = json.Unmarshal(bytes, &configMap) - if err != nil { - goto NoConfig - } - defaultBufferLen, ok := configMap["DEFAULT_BUFFER_LEN"].(int64) - if !ok || defaultBufferLen == 0 { - defaultBufferLen = 1000 - } - for name, loggerconfigInterface := range configMap { - if name == "DEFAULT_BUFFER_LEN" { - continue - } - loggerconfig, ok := loggerconfigInterface.(map[string]interface{}) - if !ok { - err = &ErrBadConfig{ - message: fmt.Sprintf("Bad configuration for %s", name), - } - goto NoConfig - } - for subname, subloggerconfigInterface := range loggerconfig { - subloggerconfig, ok := subloggerconfigInterface.(map[string]interface{}) - if !ok { - err = &ErrBadConfig{ - message: fmt.Sprintf("Bad configuration for %s:%s", name, subname), - } - goto NoConfig - } - bufferLen, ok := loggerconfig["bufferLen"].(int64) - if !ok || bufferLen == 0 { - bufferLen = defaultBufferLen - } - provider, ok := subloggerconfig["provider"].(string) - if !ok || provider == "" { - provider = subname - } - subconfigInterface, ok := subloggerconfig["config"] - - subconfig, err := json.Marshal(subconfigInterface) - if err != nil { - err = &ErrBadConfig{ - message: fmt.Sprintf("Bad configuration for %s:%s, provider %s: %v", name, subname, provider, err), - } - goto NoConfig - } - configs = append(configs, ourConfig{ - name: name, - subname: subname, - bufferLen: bufferLen, - provider: provider, - config: string(subconfig), - }) - } - } - if len(configs) == 0 { - err = &ErrBadConfig{ - message: fmt.Sprintf("Bad configuration. No loggers."), - } - goto NoConfig - } - for _, c := range configs { - NewNamedLogger(c.name, c.bufferLen, c.subname, c.provider, c.config) - } - return } -NoConfig: + // create a default log to write to console NewLogger(1000, "std", "console", `{"flags":"shortfile,shortfuncname,level,microseconds,date,shortfile", "stacktraceLevel":"error"}`) hasDefaultLogger = true - if configFile != "" && err != nil { + if err != nil { Error("Error reading provided config file: %s Err: %v", configFile, err) } } -- 2.40.1 From 04f848bce0d1c30d2c5a5b2369b24f5f141da9cb Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 28 May 2019 09:46:37 +0100 Subject: [PATCH 8/9] fix package documentation --- log.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/log.go b/log.go index 98976cc..6e874bc 100644 --- a/log.go +++ b/log.go @@ -9,7 +9,16 @@ // provided as an argument to program: --log-config-file // // This configuration file is a JSON file of the form: -// {"DEFAULT_BUFFER_LEN":1000,"default":{"bufferLen":1000,"console":{"provider":"console","config":{"colorize":true, "flags":"stdflags","stacktraceLevel","error"}}} +// { +// "DEFAULT_BUFFER_LEN":1000, +// "default": { +// "bufferLen": 1000, +// "console": { +// "provider": "console", +// "config": { "colorize": true, "flags": "stdflags", "stacktraceLevel": "error" } +// } +// } +// } package log import ( -- 2.40.1 From 7ee37ae759d22e3c7d1f3151a87d45a59705892d Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 5 Jun 2019 12:35:34 +0100 Subject: [PATCH 9/9] Adjust comment --- log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log.go b/log.go index 795fac4..1332116 100644 --- a/log.go +++ b/log.go @@ -199,7 +199,7 @@ func IsFatal() bool { return GetLevel() <= FATAL } -// Close closes the default logger +// Close closes all the loggers func Close() { NamedLoggers.Range(func(name string, logger *Logger) bool { NamedLoggers.Delete(name) -- 2.40.1