From fd4068e2fcfc3d1e4c381f095368a2e8b7a018d0 Mon Sep 17 00:00:00 2001 From: deffer Date: Mon, 23 Jan 2023 03:23:10 +0500 Subject: [PATCH 1/6] Add postgres format logs --- csv_writer.go | 36 ++++++++++++ json_writer.go | 28 +++++++++ logger.go | 87 ++++++++++++++++++++++++++++ logger_test.go | 139 +++++++++++++++++++++++++++++++++++++++++++++ logger_writer.go | 5 ++ postgres_logger.go | 80 ++++++++++++++++++++++++++ text_writer.go | 29 ++++++++++ utils.go | 14 +++++ 8 files changed, 418 insertions(+) create mode 100644 csv_writer.go create mode 100644 json_writer.go create mode 100644 logger.go create mode 100644 logger_test.go create mode 100644 logger_writer.go create mode 100644 postgres_logger.go create mode 100644 text_writer.go create mode 100644 utils.go diff --git a/csv_writer.go b/csv_writer.go new file mode 100644 index 0000000..f0e1e89 --- /dev/null +++ b/csv_writer.go @@ -0,0 +1,36 @@ +package tracelog + +import ( + "encoding/csv" + "fmt" + "io" + "sync" +) + +type csvWriter struct { + lock sync.Mutex + out io.Writer + fields []string +} + +func (csvWriter *csvWriter) Log(fields Fields) { + vals := getValuesFromMap(fields, csvWriter.fields) + stringVals := make([]string, len(vals)) + for i := range vals { + stringVals[i] = fmt.Sprint(vals[i]) + } + csvWriter.lock.Lock() + defer csvWriter.lock.Unlock() + w := csv.NewWriter(csvWriter.out) + err := w.Write(stringVals) + if err == nil { + w.Flush() + } +} + +func NewCsvWriter(out io.Writer, fields []string) LoggerWriter { + return &csvWriter{ + out: out, + fields: fields, + } +} diff --git a/json_writer.go b/json_writer.go new file mode 100644 index 0000000..4362562 --- /dev/null +++ b/json_writer.go @@ -0,0 +1,28 @@ +package tracelog + +import ( + "encoding/json" + "fmt" + "io" + "sync" +) + +type jsonWriter struct { + lock sync.Mutex + out io.Writer +} + +func (jsonWriter *jsonWriter) Log(fields Fields) { + jsonWriter.lock.Lock() + defer jsonWriter.lock.Unlock() + data, err := json.MarshalIndent(fields, "", " ") + if err == nil { + _, _ = fmt.Fprint(jsonWriter.out, string(data)) + } +} + +func NewJsonWriter(out io.Writer) LoggerWriter { + return &jsonWriter{ + out: out, + } +} diff --git a/logger.go b/logger.go new file mode 100644 index 0000000..8788389 --- /dev/null +++ b/logger.go @@ -0,0 +1,87 @@ +package tracelog + +import ( + "fmt" + "os" +) + +type LoggerType string + +const ( + InfoLoggerType LoggerType = "INFO" + WarningLoggerType LoggerType = "WARNING" + ErrorLoggerType LoggerType = "ERROR" + DebugLoggerType LoggerType = "DEBUG" +) + +type Fields map[string]interface{} +type FieldValues func() Fields + +type Logger struct { + loggerWriters []LoggerWriter + fieldValues FieldValues +} + +func NewLogger(fieldValues FieldValues, loggerWriters ...LoggerWriter) *Logger { + return &Logger{ + loggerWriters: loggerWriters, + fieldValues: fieldValues, + } +} + +func (logger *Logger) Log(v ...interface{}) { + fields := logger.fieldValues() + fields["message"] = fmt.Sprint(v...) + for _, loggerWriter := range logger.loggerWriters { + loggerWriter.Log(fields) + } +} + +func (logger *Logger) Logf(format string, v ...interface{}) { + logger.Log(fmt.Sprintf(format, v...)) +} + +func (logger *Logger) Fatalln(v ...interface{}) { + logger.Log(fmt.Sprintln(v...)) + os.Exit(1) +} + +func (logger *Logger) Fatalf(format string, v ...interface{}) { + logger.Logf(format, v...) + os.Exit(1) +} + +func (logger *Logger) Fatal(v ...interface{}) { + logger.Log(v...) + os.Exit(1) +} + +func (logger *Logger) Panicln(v ...interface{}) { + s := fmt.Sprintln(v...) + logger.Log(s) + panic(s) +} + +func (logger *Logger) Panicf(format string, v ...interface{}) { + s := fmt.Sprintf(format, v...) + logger.Log(s) + panic(s) +} + +func (logger *Logger) Panic(v ...interface{}) { + s := fmt.Sprint(v...) + logger.Log(s) + panic(s) +} + +func (logger *Logger) Println(v ...interface{}) { + logger.Log(fmt.Sprintln(v...)) +} + +func (logger *Logger) Printf(format string, v ...interface{}) { + logger.Logf(format, v...) +} + +func (logger *Logger) Print(v ...interface{}) { + logger.Log(v...) +} diff --git a/logger_test.go b/logger_test.go new file mode 100644 index 0000000..6f894d8 --- /dev/null +++ b/logger_test.go @@ -0,0 +1,139 @@ +package tracelog + +import ( + "bytes" + "fmt" + "os" + "testing" + "time" +) + +var TestBasicFormat = "%s [%d] %s: %s" +var TestBasicFields = []string{"time", "pid", "level", "message"} + +func GetFieldValuesForTest(loggerType LoggerType) func() Fields { + return func() Fields { + now := time.Now().UTC() + fields := Fields{ + "time": now.Format("2006-01-02 03:04:05 UTC"), + "pid": os.Getpid(), + "level": loggerType, + } + + return fields + } +} + +func TestLogger_PrintWithTextWriter(t *testing.T) { + message := "test" + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("%s [%d] %s: %s", now, os.Getpid(), logLevel, message) + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)) + infoPostgresLogger.Print(message) + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be: %s, got: %s", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintlnWithTextWriter(t *testing.T) { + message := "test" + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("%s [%d] %s: %s%s", now, os.Getpid(), logLevel, message, "\n") + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)) + infoPostgresLogger.Println(message) + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be: %v, got: %v", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintfWithTextWriter(t *testing.T) { + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("%s [%d] %s: %s %s", now, os.Getpid(), logLevel, "kek", "test") + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)) + infoPostgresLogger.Printf("%s %s", "kek", "test") + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be: %v, got: %v", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintWithJsonWriter(t *testing.T) { + message := "test" + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, message, os.Getpid(), now) + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)) + infoPostgresLogger.Print(message) + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be:\n %s, \ngot: \n%s", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintlnWithJsonWriter(t *testing.T) { + message := "test" + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\\n\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, message, os.Getpid(), now) + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)) + infoPostgresLogger.Println(message) + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be:\n %s, \ngot: \n%s", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintfWithJsonWriter(t *testing.T) { + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, "kek test", os.Getpid(), now) + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)) + infoPostgresLogger.Printf("%s %s", "kek", "test") + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be:\n %s, \ngot: \n%s", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintWithCsvWriter(t *testing.T) { + message := "test" + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("%s,%d,%s,%s\n", now, os.Getpid(), logLevel, message) + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)) + infoPostgresLogger.Print(message) + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be:\n %s \ngot:\n %s", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintlnWithCsvWriter(t *testing.T) { + message := "test" + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("%s,%d,%s,\"%s\n\"\n", now, os.Getpid(), logLevel, message) + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)) + infoPostgresLogger.Println(message) + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be:\n %s \ngot:\n %s", expectedOutput, buffer.String()) + } +} + +func TestLogger_PrintfWithCsvWriter(t *testing.T) { + logLevel := InfoLoggerType + now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") + expectedOutput := fmt.Sprintf("%s,%d,%s,%s\n", now, os.Getpid(), logLevel, "kek test") + buffer := bytes.Buffer{} + infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)) + infoPostgresLogger.Printf("%s %s", "kek", "test") + if expectedOutput != buffer.String() { + t.Errorf("\nOutput should be:\n %s \ngot:\n %s", expectedOutput, buffer.String()) + } +} diff --git a/logger_writer.go b/logger_writer.go new file mode 100644 index 0000000..ef11c67 --- /dev/null +++ b/logger_writer.go @@ -0,0 +1,5 @@ +package tracelog + +type LoggerWriter interface { + Log(Fields) +} diff --git a/postgres_logger.go b/postgres_logger.go new file mode 100644 index 0000000..6fccdc7 --- /dev/null +++ b/postgres_logger.go @@ -0,0 +1,80 @@ +package tracelog + +import ( + "io/ioutil" + "os" + "time" +) + +type PostgresLogger struct { + *Logger +} + +var BasicFormat = "%s [%d] %s: %s" +var BasicFields = []string{"timestamp", "pid", "error_severity", "message"} + +func GetFieldValues(loggerType LoggerType) func() Fields { + return func() Fields { + now := time.Now().UTC() + fields := Fields{ + "timestamp": now.Format("2006-01-02 03:04:05.000 UTC"), + "pid": os.Getpid(), + "error_severity": loggerType, + } + + return fields + } +} + +var InfoPostgresLogger = NewPostgresLogger(GetFieldValues(InfoLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) +var WarningPostgresLogger = NewPostgresLogger(GetFieldValues(WarningLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) +var ErrorPostgresLogger = NewPostgresLogger(GetFieldValues(ErrorLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) +var DebugPostgresLogger = NewPostgresLogger(GetFieldValues(DebugLoggerType), NewTextWriter(ioutil.Discard, BasicFormat, BasicFields)) + +func NewPostgresLogger(fieldValues FieldValues, loggerWriters ...LoggerWriter) *PostgresLogger { + return &PostgresLogger{ + NewLogger(fieldValues, loggerWriters...), + } +} + +func (logger *PostgresLogger) PanicError(err error) { + logger.Panic(err) +} + +func (logger *PostgresLogger) PanicfOnError(format string, err error) { + if err != nil { + logger.Panicf(format, err) + } +} + +func (logger *PostgresLogger) PanicOnError(err error) { + if err != nil { + logger.PanicError(err) + } +} + +func (logger *PostgresLogger) FatalError(err error) { + logger.Fatal(err) +} + +func (logger *PostgresLogger) FatalfOnError(format string, err error) { + if err != nil { + logger.Fatalf(format, err) + } +} + +func (logger *PostgresLogger) FatalOnError(err error) { + if err != nil { + logger.FatalError(err) + } +} + +func (logger *PostgresLogger) PrintError(err error) { + logger.Println(err) +} + +func (logger *PostgresLogger) PrintOnError(err error) { + if err != nil { + logger.PrintError(err) + } +} diff --git a/text_writer.go b/text_writer.go new file mode 100644 index 0000000..cf8cbc6 --- /dev/null +++ b/text_writer.go @@ -0,0 +1,29 @@ +package tracelog + +import ( + "fmt" + "io" + "sync" +) + +type textWriter struct { + lock sync.Mutex + out io.Writer + format string + fields []string +} + +func (textWriter *textWriter) Log(fields Fields) { + vals := getValuesFromMap(fields, textWriter.fields) + textWriter.lock.Lock() + defer textWriter.lock.Unlock() + _, _ = fmt.Fprintf(textWriter.out, textWriter.format, vals...) +} + +func NewTextWriter(out io.Writer, format string, fields []string) LoggerWriter { + return &textWriter{ + out: out, + format: format, + fields: fields, + } +} diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..a8534fa --- /dev/null +++ b/utils.go @@ -0,0 +1,14 @@ +package tracelog + +func getValuesFromMap(fieldsMap Fields, fields []string) []interface{} { + vals := make([]interface{}, len(fields)) + for i, field := range fields { + var ok bool + vals[i], ok = fieldsMap[field] + if !ok { + vals[i] = "???" + } + } + + return vals +} From 706a2dba0355c0db4d04f9e7bfa2023a4909ec1c Mon Sep 17 00:00:00 2001 From: deffer Date: Mon, 23 Jan 2023 03:28:44 +0500 Subject: [PATCH 2/6] Fix NewLogLevelError --- logging.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/logging.go b/logging.go index 74b8290..127f458 100644 --- a/logging.go +++ b/logging.go @@ -45,8 +45,8 @@ type LogLevelError struct { error } -func NewLogLevelError() LogLevelError { - return LogLevelError{errors.Errorf("got incorrect log level: '%s', expected one of: '%v'", logLevel, LogLevels)} +func NewLogLevelError(incorrectLogLevel string) LogLevelError { + return LogLevelError{errors.Errorf("got incorrect log level: '%s', expected one of: '%v'", incorrectLogLevel, LogLevels)} } func (err LogLevelError) Error() string { @@ -65,7 +65,7 @@ func UpdateLogLevel(newLevel string) error { } } if !isCorrect { - return NewLogLevelError() + return NewLogLevelError(newLevel) } logLevel = newLevel From 00e3507ce8b1b4c619631320eee990eedd8fd255 Mon Sep 17 00:00:00 2001 From: deffer Date: Mon, 23 Jan 2023 16:01:37 +0500 Subject: [PATCH 3/6] Fixiki --- logger.go | 56 +++++++++++-- logger_test.go | 196 ++++++++++++++++++++++++--------------------- postgres_logger.go | 56 +------------ 3 files changed, 157 insertions(+), 151 deletions(-) diff --git a/logger.go b/logger.go index 8788389..64e43aa 100644 --- a/logger.go +++ b/logger.go @@ -18,23 +18,21 @@ type Fields map[string]interface{} type FieldValues func() Fields type Logger struct { - loggerWriters []LoggerWriter - fieldValues FieldValues + loggerWriter LoggerWriter + fieldValues FieldValues } -func NewLogger(fieldValues FieldValues, loggerWriters ...LoggerWriter) *Logger { +func NewLogger(fieldValues FieldValues, loggerWriter LoggerWriter) *Logger { return &Logger{ - loggerWriters: loggerWriters, - fieldValues: fieldValues, + loggerWriter: loggerWriter, + fieldValues: fieldValues, } } func (logger *Logger) Log(v ...interface{}) { fields := logger.fieldValues() fields["message"] = fmt.Sprint(v...) - for _, loggerWriter := range logger.loggerWriters { - loggerWriter.Log(fields) - } + logger.loggerWriter.Log(fields) } func (logger *Logger) Logf(format string, v ...interface{}) { @@ -85,3 +83,45 @@ func (logger *Logger) Printf(format string, v ...interface{}) { func (logger *Logger) Print(v ...interface{}) { logger.Log(v...) } + +func (logger *Logger) PanicError(err error) { + logger.Panic(err) +} + +func (logger *Logger) PanicfOnError(format string, err error) { + if err != nil { + logger.Panicf(format, err) + } +} + +func (logger *Logger) PanicOnError(err error) { + if err != nil { + logger.PanicError(err) + } +} + +func (logger *Logger) FatalError(err error) { + logger.Fatal(err) +} + +func (logger *Logger) FatalfOnError(format string, err error) { + if err != nil { + logger.Fatalf(format, err) + } +} + +func (logger *Logger) FatalOnError(err error) { + if err != nil { + logger.FatalError(err) + } +} + +func (logger *Logger) PrintError(err error) { + logger.Println(err) +} + +func (logger *Logger) PrintOnError(err error) { + if err != nil { + logger.PrintError(err) + } +} diff --git a/logger_test.go b/logger_test.go index 6f894d8..ea47e66 100644 --- a/logger_test.go +++ b/logger_test.go @@ -24,116 +24,130 @@ func GetFieldValuesForTest(loggerType LoggerType) func() Fields { } } -func TestLogger_PrintWithTextWriter(t *testing.T) { +func TestLogger_PrintWith(t *testing.T) { message := "test" logLevel := InfoLoggerType now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("%s [%d] %s: %s", now, os.Getpid(), logLevel, message) buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)) - infoPostgresLogger.Print(message) - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be: %s, got: %s", expectedOutput, buffer.String()) + tests := []struct { + name string + input string + want string + infoLogger *Logger + }{ + { + "TextWriter", + message, + fmt.Sprintf("%s [%d] %s: %s", now, os.Getpid(), logLevel, message), + NewLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)), + }, + { + "JsonWriter", + message, + fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, message, os.Getpid(), now), + NewLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)), + }, + { + "CsvWriter", + message, + fmt.Sprintf("%s,%d,%s,%s\n", now, os.Getpid(), logLevel, message), + NewLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)), + }, } -} - -func TestLogger_PrintlnWithTextWriter(t *testing.T) { - message := "test" - logLevel := InfoLoggerType - now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("%s [%d] %s: %s%s", now, os.Getpid(), logLevel, message, "\n") - buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)) - infoPostgresLogger.Println(message) - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be: %v, got: %v", expectedOutput, buffer.String()) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.infoLogger.Print(tt.input) + if tt.want != buffer.String() { + t.Errorf("\\nOutput should be:\\n %s, \\ngot: \\n%s\"", tt.want, buffer.String()) + } + buffer.Reset() + }) } } -func TestLogger_PrintfWithTextWriter(t *testing.T) { - logLevel := InfoLoggerType - now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("%s [%d] %s: %s %s", now, os.Getpid(), logLevel, "kek", "test") - buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)) - infoPostgresLogger.Printf("%s %s", "kek", "test") - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be: %v, got: %v", expectedOutput, buffer.String()) - } -} - -func TestLogger_PrintWithJsonWriter(t *testing.T) { +func TestLogger_PrintlnWith(t *testing.T) { message := "test" logLevel := InfoLoggerType now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, message, os.Getpid(), now) buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)) - infoPostgresLogger.Print(message) - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be:\n %s, \ngot: \n%s", expectedOutput, buffer.String()) + tests := []struct { + name string + input string + want string + infoLogger *Logger + }{ + { + "TextWriter", + message, + fmt.Sprintf("%s [%d] %s: %s%s", now, os.Getpid(), logLevel, message, "\n"), + NewLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)), + }, + { + "JsonWriter", + message, + fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\\n\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, message, os.Getpid(), now), + NewLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)), + }, + { + "CsvWriter", + message, + fmt.Sprintf("%s,%d,%s,\"%s\n\"\n", now, os.Getpid(), logLevel, message), + NewLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)), + }, } -} - -func TestLogger_PrintlnWithJsonWriter(t *testing.T) { - message := "test" - logLevel := InfoLoggerType - now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\\n\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, message, os.Getpid(), now) - buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)) - infoPostgresLogger.Println(message) - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be:\n %s, \ngot: \n%s", expectedOutput, buffer.String()) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.infoLogger.Println(tt.input) + if tt.want != buffer.String() { + t.Errorf("\\nOutput should be:\\n %s, \\ngot: \\n%s\"", tt.want, buffer.String()) + } + buffer.Reset() + }) } } -func TestLogger_PrintfWithJsonWriter(t *testing.T) { +func TestLogger_PrintfWith(t *testing.T) { + format := "%s %s" + messages := []string{"kek", "test"} logLevel := InfoLoggerType now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, "kek test", os.Getpid(), now) buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)) - infoPostgresLogger.Printf("%s %s", "kek", "test") - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be:\n %s, \ngot: \n%s", expectedOutput, buffer.String()) + tests := []struct { + name string + format string + input []string + want string + infoLogger *Logger + }{ + { + "TextWriter", + format, + messages, + fmt.Sprintf("%s [%d] %s: %s %s", now, os.Getpid(), logLevel, "kek", "test"), + NewLogger(GetFieldValuesForTest(logLevel), NewTextWriter(&buffer, TestBasicFormat, TestBasicFields)), + }, + { + "JsonWriter", + format, + messages, + fmt.Sprintf("{\n \"level\": \"%s\",\n \"message\": \"%s\",\n \"pid\": %d,\n \"time\": \"%s\"\n}", logLevel, "kek test", os.Getpid(), now), + NewLogger(GetFieldValuesForTest(logLevel), NewJsonWriter(&buffer)), + }, + { + "CsvWriter", + format, + messages, + fmt.Sprintf("%s,%d,%s,%s\n", now, os.Getpid(), logLevel, "kek test"), + NewLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)), + }, } -} - -func TestLogger_PrintWithCsvWriter(t *testing.T) { - message := "test" - logLevel := InfoLoggerType - now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("%s,%d,%s,%s\n", now, os.Getpid(), logLevel, message) - buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)) - infoPostgresLogger.Print(message) - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be:\n %s \ngot:\n %s", expectedOutput, buffer.String()) - } -} - -func TestLogger_PrintlnWithCsvWriter(t *testing.T) { - message := "test" - logLevel := InfoLoggerType - now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("%s,%d,%s,\"%s\n\"\n", now, os.Getpid(), logLevel, message) - buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)) - infoPostgresLogger.Println(message) - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be:\n %s \ngot:\n %s", expectedOutput, buffer.String()) - } -} - -func TestLogger_PrintfWithCsvWriter(t *testing.T) { - logLevel := InfoLoggerType - now := time.Now().UTC().Format("2006-01-02 03:04:05 UTC") - expectedOutput := fmt.Sprintf("%s,%d,%s,%s\n", now, os.Getpid(), logLevel, "kek test") - buffer := bytes.Buffer{} - infoPostgresLogger := NewPostgresLogger(GetFieldValuesForTest(logLevel), NewCsvWriter(&buffer, TestBasicFields)) - infoPostgresLogger.Printf("%s %s", "kek", "test") - if expectedOutput != buffer.String() { - t.Errorf("\nOutput should be:\n %s \ngot:\n %s", expectedOutput, buffer.String()) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.infoLogger.Printf(tt.format, tt.input[0], tt.input[1]) + if tt.want != buffer.String() { + t.Errorf("\\nOutput should be:\\n %s, \\ngot: \\n%s\"", tt.want, buffer.String()) + } + buffer.Reset() + }) } } diff --git a/postgres_logger.go b/postgres_logger.go index 6fccdc7..76d75e4 100644 --- a/postgres_logger.go +++ b/postgres_logger.go @@ -26,55 +26,7 @@ func GetFieldValues(loggerType LoggerType) func() Fields { } } -var InfoPostgresLogger = NewPostgresLogger(GetFieldValues(InfoLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) -var WarningPostgresLogger = NewPostgresLogger(GetFieldValues(WarningLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) -var ErrorPostgresLogger = NewPostgresLogger(GetFieldValues(ErrorLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) -var DebugPostgresLogger = NewPostgresLogger(GetFieldValues(DebugLoggerType), NewTextWriter(ioutil.Discard, BasicFormat, BasicFields)) - -func NewPostgresLogger(fieldValues FieldValues, loggerWriters ...LoggerWriter) *PostgresLogger { - return &PostgresLogger{ - NewLogger(fieldValues, loggerWriters...), - } -} - -func (logger *PostgresLogger) PanicError(err error) { - logger.Panic(err) -} - -func (logger *PostgresLogger) PanicfOnError(format string, err error) { - if err != nil { - logger.Panicf(format, err) - } -} - -func (logger *PostgresLogger) PanicOnError(err error) { - if err != nil { - logger.PanicError(err) - } -} - -func (logger *PostgresLogger) FatalError(err error) { - logger.Fatal(err) -} - -func (logger *PostgresLogger) FatalfOnError(format string, err error) { - if err != nil { - logger.Fatalf(format, err) - } -} - -func (logger *PostgresLogger) FatalOnError(err error) { - if err != nil { - logger.FatalError(err) - } -} - -func (logger *PostgresLogger) PrintError(err error) { - logger.Println(err) -} - -func (logger *PostgresLogger) PrintOnError(err error) { - if err != nil { - logger.PrintError(err) - } -} +var InfoPostgresLogger = NewLogger(GetFieldValues(InfoLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) +var WarningPostgresLogger = NewLogger(GetFieldValues(WarningLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) +var ErrorPostgresLogger = NewLogger(GetFieldValues(ErrorLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) +var DebugPostgresLogger = NewLogger(GetFieldValues(DebugLoggerType), NewTextWriter(ioutil.Discard, BasicFormat, BasicFields)) From 764866dd110748c70130871c19a30e8709aec3ed Mon Sep 17 00:00:00 2001 From: deffer Date: Tue, 24 Jan 2023 22:50:31 +0500 Subject: [PATCH 4/6] Delete Error Logger --- error_logger.go | 56 ------------------------------------- logging.go | 65 +++++++++++++++++++++++++++++++----------- postgres_logger.go | 70 ++++++++++++++++++++++++++++++++++++++-------- walg_logger.go | 43 ++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 84 deletions(-) delete mode 100644 error_logger.go create mode 100644 walg_logger.go diff --git a/error_logger.go b/error_logger.go deleted file mode 100644 index 0abdf3b..0000000 --- a/error_logger.go +++ /dev/null @@ -1,56 +0,0 @@ -package tracelog - -import ( - "io" - "log" -) - -type errorLogger struct { - *log.Logger -} - -func NewErrorLogger(out io.Writer, prefix string) *errorLogger { - return &errorLogger{log.New(out, prefix, timeFlags)} -} - -func (logger *errorLogger) PanicError(err error) { - logger.Panicf(GetErrorFormatter(), err) -} - -func (logger *errorLogger) PanicfOnError(format string, err error) { - if err != nil { - logger.Panicf(format, err) - } -} - -func (logger *errorLogger) PanicOnError(err error) { - if err != nil { - logger.PanicError(err) - } -} - -func (logger *errorLogger) FatalError(err error) { - logger.Fatalf(GetErrorFormatter(), err) -} - -func (logger *errorLogger) FatalfOnError(format string, err error) { - if err != nil { - logger.Fatalf(format, err) - } -} - -func (logger *errorLogger) FatalOnError(err error) { - if err != nil { - logger.FatalError(err) - } -} - -func (logger *errorLogger) PrintError(err error) { - logger.Printf(GetErrorFormatter()+"\n", err) -} - -func (logger *errorLogger) PrintOnError(err error) { - if err != nil { - logger.PrintError(err) - } -} diff --git a/logging.go b/logging.go index 127f458..143ca6b 100644 --- a/logging.go +++ b/logging.go @@ -2,24 +2,28 @@ package tracelog import ( "fmt" - "io/ioutil" - "log" - "os" - "github.com/pkg/errors" + "io/ioutil" + "strings" ) const ( NormalLogLevel = "NORMAL" DevelLogLevel = "DEVEL" ErrorLogLevel = "ERROR" - timeFlags = log.LstdFlags | log.Lmicroseconds ) -var InfoLogger = NewErrorLogger(os.Stdout, "INFO: ") -var WarningLogger = NewErrorLogger(os.Stdout, "WARNING: ") -var ErrorLogger = NewErrorLogger(os.Stderr, "ERROR: ") -var DebugLogger = NewErrorLogger(ioutil.Discard, "DEBUG: ") +const ( + CsvPg = "CSV PG" + JsonPg = "JSON PG" + TextPg = "TEXT PG" + TextWalg = "TEXT WALG" +) + +var InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), WalgDefaultWriter) +var WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), WalgDefaultWriter) +var ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), WalgDefaultWriter) +var DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormatForDebug, WalgTextFormatFields)) var LogLevels = []string{NormalLogLevel, DevelLogLevel, ErrorLogLevel} var logLevel = NormalLogLevel @@ -29,15 +33,18 @@ var logLevelFormatters = map[string]string{ DevelLogLevel: "%+v", } +var LogWriters = []string{CsvPg, JsonPg, TextPg, TextWalg} +var logWriter = TextWalg + func setupLoggers() { - if logLevel == NormalLogLevel { - DebugLogger = NewErrorLogger(ioutil.Discard, "DEBUG: ") - } else if logLevel == ErrorLogLevel { - DebugLogger = NewErrorLogger(ioutil.Discard, "DEBUG: ") - InfoLogger = NewErrorLogger(ioutil.Discard, "INFO: ") - WarningLogger = NewErrorLogger(ioutil.Discard, "WARNING: ") - } else { - DebugLogger = NewErrorLogger(os.Stdout, "DEBUG: ") + if logWriter == TextWalg { + setupWalgLoggers() + } else if logWriter == JsonPg { + setupJsonPgLoggers() + } else if logWriter == CsvPg { + setupCsvPgLoggers() + } else if logWriter == TextPg { + setupTextPgLoggers() } } @@ -49,6 +56,14 @@ func NewLogLevelError(incorrectLogLevel string) LogLevelError { return LogLevelError{errors.Errorf("got incorrect log level: '%s', expected one of: '%v'", incorrectLogLevel, LogLevels)} } +type LogWriterError struct { + error +} + +func NewLogWriterError(incorrectLogWriter string) LogWriterError { + return LogWriterError{errors.Errorf("got incorrect log writer: '%s', expected one of: '%v'", incorrectLogWriter, strings.Join(LogWriters[:], ","))} +} + func (err LogLevelError) Error() string { return fmt.Sprintf(GetErrorFormatter(), err.error) } @@ -72,3 +87,19 @@ func UpdateLogLevel(newLevel string) error { setupLoggers() return nil } + +func UpdateLogWriter(newWriter string) error { + isCorrect := false + for _, logWriter := range LogWriters { + if newWriter == logWriter { + isCorrect = true + } + } + if !isCorrect { + return NewLogWriterError(newWriter) + } + + logWriter = newWriter + setupLoggers() + return nil +} diff --git a/postgres_logger.go b/postgres_logger.go index 76d75e4..435fbea 100644 --- a/postgres_logger.go +++ b/postgres_logger.go @@ -6,14 +6,10 @@ import ( "time" ) -type PostgresLogger struct { - *Logger -} - -var BasicFormat = "%s [%d] %s: %s" -var BasicFields = []string{"timestamp", "pid", "error_severity", "message"} +var PgFormat = "%s [%d] %s: %s" +var PgFields = []string{"timestamp", "pid", "error_severity", "message"} -func GetFieldValues(loggerType LoggerType) func() Fields { +func GetFieldValuesForPg(loggerType LoggerType) func() Fields { return func() Fields { now := time.Now().UTC() fields := Fields{ @@ -26,7 +22,59 @@ func GetFieldValues(loggerType LoggerType) func() Fields { } } -var InfoPostgresLogger = NewLogger(GetFieldValues(InfoLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) -var WarningPostgresLogger = NewLogger(GetFieldValues(WarningLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) -var ErrorPostgresLogger = NewLogger(GetFieldValues(ErrorLoggerType), NewTextWriter(os.Stderr, BasicFormat, BasicFields)) -var DebugPostgresLogger = NewLogger(GetFieldValues(DebugLoggerType), NewTextWriter(ioutil.Discard, BasicFormat, BasicFields)) +func setupJsonPgLoggers() { + if logLevel == NormalLogLevel { + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewJsonWriter(ioutil.Discard)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewJsonWriter(os.Stderr)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewJsonWriter(os.Stderr)) + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewJsonWriter(os.Stderr)) + } else if logLevel == ErrorLogLevel { + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewJsonWriter(os.Stderr)) + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewJsonWriter(ioutil.Discard)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewJsonWriter(ioutil.Discard)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewJsonWriter(ioutil.Discard)) + } else { + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewJsonWriter(os.Stdout)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewJsonWriter(os.Stderr)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewJsonWriter(os.Stderr)) + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewJsonWriter(os.Stderr)) + } +} + +func setupTextPgLoggers() { + if logLevel == NormalLogLevel { + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + } else if logLevel == ErrorLogLevel { + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) + } else { + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewTextWriter(os.Stdout, PgFormat, PgFields)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) + } +} + +func setupCsvPgLoggers() { + if logLevel == NormalLogLevel { + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewCsvWriter(os.Stderr, PgFields)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewCsvWriter(os.Stderr, PgFields)) + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewCsvWriter(os.Stderr, PgFields)) + } else if logLevel == ErrorLogLevel { + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewCsvWriter(os.Stderr, PgFields)) + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) + } else { + DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewCsvWriter(os.Stdout, PgFields)) + InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewCsvWriter(os.Stderr, PgFields)) + WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewCsvWriter(os.Stderr, PgFields)) + ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewCsvWriter(os.Stderr, PgFields)) + } +} diff --git a/walg_logger.go b/walg_logger.go new file mode 100644 index 0000000..72d419b --- /dev/null +++ b/walg_logger.go @@ -0,0 +1,43 @@ +package tracelog + +import ( + "io/ioutil" + "os" + "time" +) + +var WalgTextFormat = "%s: %s %v" +var WalgTextFormatForDebug = "%s: %s %+v" +var WalgTextFormatFields = []string{"level", "time", "message"} +var WalgDefaultWriter = NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields) + +func GetFieldValuesForWalg(loggerType LoggerType) func() Fields { + return func() Fields { + now := time.Now() + fields := Fields{ + "level": loggerType, + "time": now.Format("2006/01/02 03:04:05.000000"), + } + + return fields + } +} + +func setupWalgLoggers() { + if logLevel == NormalLogLevel { + DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) + InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + } else if logLevel == ErrorLogLevel { + ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) + InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) + WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) + } else { + DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(os.Stdout, WalgTextFormat, WalgTextFormatFields)) + InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) + } +} From 8536e6c0e211e3a77bc6e6cbdd0bb5de570fd33d Mon Sep 17 00:00:00 2001 From: deffer Date: Wed, 25 Jan 2023 16:13:42 +0500 Subject: [PATCH 5/6] Refactoring --- logging.go | 38 +++++++++++++++++++++++------ postgres_logger.go | 59 ++++------------------------------------------ walg_logger.go | 21 +++-------------- 3 files changed, 39 insertions(+), 79 deletions(-) diff --git a/logging.go b/logging.go index 143ca6b..ec15988 100644 --- a/logging.go +++ b/logging.go @@ -3,7 +3,9 @@ package tracelog import ( "fmt" "github.com/pkg/errors" + "io" "io/ioutil" + "os" "strings" ) @@ -36,15 +38,37 @@ var logLevelFormatters = map[string]string{ var LogWriters = []string{CsvPg, JsonPg, TextPg, TextWalg} var logWriter = TextWalg -func setupLoggers() { +type GetWriter func(out io.Writer) LoggerWriter +type GetFieldValues func(loggerType LoggerType) func() Fields + +func setupLoggersDependingOnWriter() { if logWriter == TextWalg { - setupWalgLoggers() + setupLoggers(GetWalgWriter, GetFieldValuesForWalg) } else if logWriter == JsonPg { - setupJsonPgLoggers() + setupLoggers(NewJsonWriter, GetFieldValuesForPg) } else if logWriter == CsvPg { - setupCsvPgLoggers() + setupLoggers(GetPgCsvWriter, GetFieldValuesForPg) } else if logWriter == TextPg { - setupTextPgLoggers() + setupLoggers(GetPgTextWriter, GetFieldValuesForPg) + } +} + +func setupLoggers(writer GetWriter, getFieldValues GetFieldValues) { + if logLevel == NormalLogLevel { + DebugLogger = NewLogger(getFieldValues(DebugLoggerType), writer(ioutil.Discard)) + InfoLogger = NewLogger(getFieldValues(InfoLoggerType), writer(os.Stderr)) + WarningLogger = NewLogger(getFieldValues(WarningLoggerType), writer(os.Stderr)) + ErrorLogger = NewLogger(getFieldValues(ErrorLoggerType), writer(os.Stderr)) + } else if logLevel == ErrorLogLevel { + ErrorLogger = NewLogger(getFieldValues(ErrorLoggerType), writer(os.Stderr)) + DebugLogger = NewLogger(getFieldValues(DebugLoggerType), writer(ioutil.Discard)) + InfoLogger = NewLogger(getFieldValues(InfoLoggerType), writer(ioutil.Discard)) + WarningLogger = NewLogger(getFieldValues(WarningLoggerType), writer(ioutil.Discard)) + } else { + DebugLogger = NewLogger(getFieldValues(DebugLoggerType), writer(os.Stdout)) + InfoLogger = NewLogger(getFieldValues(InfoLoggerType), writer(os.Stderr)) + WarningLogger = NewLogger(getFieldValues(WarningLoggerType), writer(os.Stderr)) + ErrorLogger = NewLogger(getFieldValues(ErrorLoggerType), writer(os.Stderr)) } } @@ -84,7 +108,7 @@ func UpdateLogLevel(newLevel string) error { } logLevel = newLevel - setupLoggers() + setupLoggersDependingOnWriter() return nil } @@ -100,6 +124,6 @@ func UpdateLogWriter(newWriter string) error { } logWriter = newWriter - setupLoggers() + setupLoggersDependingOnWriter() return nil } diff --git a/postgres_logger.go b/postgres_logger.go index 435fbea..9e6d2c9 100644 --- a/postgres_logger.go +++ b/postgres_logger.go @@ -1,7 +1,7 @@ package tracelog import ( - "io/ioutil" + "io" "os" "time" ) @@ -22,59 +22,10 @@ func GetFieldValuesForPg(loggerType LoggerType) func() Fields { } } -func setupJsonPgLoggers() { - if logLevel == NormalLogLevel { - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewJsonWriter(ioutil.Discard)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewJsonWriter(os.Stderr)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewJsonWriter(os.Stderr)) - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewJsonWriter(os.Stderr)) - } else if logLevel == ErrorLogLevel { - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewJsonWriter(os.Stderr)) - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewJsonWriter(ioutil.Discard)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewJsonWriter(ioutil.Discard)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewJsonWriter(ioutil.Discard)) - } else { - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewJsonWriter(os.Stdout)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewJsonWriter(os.Stderr)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewJsonWriter(os.Stderr)) - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewJsonWriter(os.Stderr)) - } +func GetPgTextWriter(out io.Writer) LoggerWriter { + return NewTextWriter(out, PgFormat, PgFields) } -func setupTextPgLoggers() { - if logLevel == NormalLogLevel { - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - } else if logLevel == ErrorLogLevel { - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewTextWriter(ioutil.Discard, PgFormat, PgFields)) - } else { - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewTextWriter(os.Stdout, PgFormat, PgFields)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewTextWriter(os.Stderr, PgFormat, PgFields)) - } -} - -func setupCsvPgLoggers() { - if logLevel == NormalLogLevel { - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewCsvWriter(os.Stderr, PgFields)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewCsvWriter(os.Stderr, PgFields)) - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewCsvWriter(os.Stderr, PgFields)) - } else if logLevel == ErrorLogLevel { - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewCsvWriter(os.Stderr, PgFields)) - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewCsvWriter(ioutil.Discard, PgFields)) - } else { - DebugLogger = NewLogger(GetFieldValuesForPg(DebugLoggerType), NewCsvWriter(os.Stdout, PgFields)) - InfoLogger = NewLogger(GetFieldValuesForPg(InfoLoggerType), NewCsvWriter(os.Stderr, PgFields)) - WarningLogger = NewLogger(GetFieldValuesForPg(WarningLoggerType), NewCsvWriter(os.Stderr, PgFields)) - ErrorLogger = NewLogger(GetFieldValuesForPg(ErrorLoggerType), NewCsvWriter(os.Stderr, PgFields)) - } +func GetPgCsvWriter(out io.Writer) LoggerWriter { + return NewCsvWriter(out, PgFields) } diff --git a/walg_logger.go b/walg_logger.go index 72d419b..e275423 100644 --- a/walg_logger.go +++ b/walg_logger.go @@ -1,7 +1,7 @@ package tracelog import ( - "io/ioutil" + "io" "os" "time" ) @@ -23,21 +23,6 @@ func GetFieldValuesForWalg(loggerType LoggerType) func() Fields { } } -func setupWalgLoggers() { - if logLevel == NormalLogLevel { - DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) - InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - } else if logLevel == ErrorLogLevel { - ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) - InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) - WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), NewTextWriter(ioutil.Discard, WalgTextFormat, WalgTextFormatFields)) - } else { - DebugLogger = NewLogger(GetFieldValuesForWalg(DebugLoggerType), NewTextWriter(os.Stdout, WalgTextFormat, WalgTextFormatFields)) - InfoLogger = NewLogger(GetFieldValuesForWalg(InfoLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - WarningLogger = NewLogger(GetFieldValuesForWalg(WarningLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - ErrorLogger = NewLogger(GetFieldValuesForWalg(ErrorLoggerType), NewTextWriter(os.Stderr, WalgTextFormat, WalgTextFormatFields)) - } +func GetWalgWriter(out io.Writer) LoggerWriter { + return NewTextWriter(out, WalgTextFormat, WalgTextFormatFields) } From 64e0c2f4be416aabbf466dd4ffed470d9fa1cc90 Mon Sep 17 00:00:00 2001 From: deffer Date: Wed, 25 Jan 2023 16:44:18 +0500 Subject: [PATCH 6/6] Refactoring --- logging.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/logging.go b/logging.go index ec15988..c966ae7 100644 --- a/logging.go +++ b/logging.go @@ -56,9 +56,6 @@ func setupLoggersDependingOnWriter() { func setupLoggers(writer GetWriter, getFieldValues GetFieldValues) { if logLevel == NormalLogLevel { DebugLogger = NewLogger(getFieldValues(DebugLoggerType), writer(ioutil.Discard)) - InfoLogger = NewLogger(getFieldValues(InfoLoggerType), writer(os.Stderr)) - WarningLogger = NewLogger(getFieldValues(WarningLoggerType), writer(os.Stderr)) - ErrorLogger = NewLogger(getFieldValues(ErrorLoggerType), writer(os.Stderr)) } else if logLevel == ErrorLogLevel { ErrorLogger = NewLogger(getFieldValues(ErrorLoggerType), writer(os.Stderr)) DebugLogger = NewLogger(getFieldValues(DebugLoggerType), writer(ioutil.Discard)) @@ -66,6 +63,9 @@ func setupLoggers(writer GetWriter, getFieldValues GetFieldValues) { WarningLogger = NewLogger(getFieldValues(WarningLoggerType), writer(ioutil.Discard)) } else { DebugLogger = NewLogger(getFieldValues(DebugLoggerType), writer(os.Stdout)) + } + + if logLevel == NormalLogLevel || logLevel == DevelLogLevel { InfoLogger = NewLogger(getFieldValues(InfoLoggerType), writer(os.Stderr)) WarningLogger = NewLogger(getFieldValues(WarningLoggerType), writer(os.Stderr)) ErrorLogger = NewLogger(getFieldValues(ErrorLoggerType), writer(os.Stderr)) @@ -77,7 +77,7 @@ type LogLevelError struct { } func NewLogLevelError(incorrectLogLevel string) LogLevelError { - return LogLevelError{errors.Errorf("got incorrect log level: '%s', expected one of: '%v'", incorrectLogLevel, LogLevels)} + return LogLevelError{errors.Errorf("got incorrect log level: '%s', expected one of: '%v'", incorrectLogLevel, strings.Join(LogLevels[:], ", "))} } type LogWriterError struct { @@ -85,7 +85,7 @@ type LogWriterError struct { } func NewLogWriterError(incorrectLogWriter string) LogWriterError { - return LogWriterError{errors.Errorf("got incorrect log writer: '%s', expected one of: '%v'", incorrectLogWriter, strings.Join(LogWriters[:], ","))} + return LogWriterError{errors.Errorf("got incorrect log writer: '%s', expected one of: '%v'", incorrectLogWriter, strings.Join(LogWriters[:], ", "))} } func (err LogLevelError) Error() string {