go-mail/log/jsonlog_test.go
Winni Neessen 77d9e3d02a
#142 Add structured JSON logger and associated tests
This commit introduces a new type 'JSONlog' that satisfies the Logger interface for structured JSON logging. This includes new methods 'Debugf', 'Infof', 'Warnf' and 'Errorf' to log messages at different levels and an associated test 'jsonlog_test.go' to ensure correct functionality. This enhances the logging functionality by providing clarity in logs and eases debugging process.
2023-08-23 11:16:23 +02:00

297 lines
8.6 KiB
Go

// SPDX-FileCopyrightText: Copyright (c) 2023 The go-mail Authors
//
// SPDX-License-Identifier: MIT
//go:build go1.21
// +build go1.21
package log
import (
"bytes"
"encoding/json"
"fmt"
"testing"
"time"
)
type jsonLog struct {
Direction jsonDir `json:"direction"`
Level string `json:"level"`
Message string `json:"msg"`
Time time.Time `json:"time"`
}
type jsonDir struct {
From string `json:"from"`
To string `json:"to"`
}
func TestNewJSON(t *testing.T) {
var b bytes.Buffer
l := NewJSON(&b, LevelDebug)
if l.l != LevelDebug {
t.Error("Expected level to be LevelDebug, got ", l.l)
}
if l.log == nil {
t.Error("logger not initialized")
}
}
func TestJSONDebugf(t *testing.T) {
var b bytes.Buffer
l := NewJSON(&b, LevelDebug)
f := "test %s"
msg := "foo"
msg2 := "bar"
l.Debugf(Log{Direction: DirServerToClient, Format: f, Messages: []interface{}{msg}})
exFrom := "server"
exTo := "client"
jl, err := unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg, jl.Message)
}
b.Reset()
l.Debugf(Log{Direction: DirClientToServer, Format: f, Messages: []interface{}{msg2}})
exFrom = "client"
exTo = "server"
jl, err = unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg2) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg2, jl.Message)
}
b.Reset()
l.l = LevelInfo
l.Debugf(Log{Direction: DirServerToClient, Format: "test %s", Messages: []interface{}{"foo"}})
if b.String() != "" {
t.Error("Debug message was not expected to be logged")
}
}
func TestJSONDebugf_WithDefault(t *testing.T) {
var b bytes.Buffer
l := NewJSON(&b, 999)
f := "test %s"
msg := "foo"
msg2 := "bar"
l.Debugf(Log{Direction: DirServerToClient, Format: f, Messages: []interface{}{msg}})
exFrom := "server"
exTo := "client"
jl, err := unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg, jl.Message)
}
b.Reset()
l.Debugf(Log{Direction: DirClientToServer, Format: f, Messages: []interface{}{msg2}})
exFrom = "client"
exTo = "server"
jl, err = unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg2) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg2, jl.Message)
}
b.Reset()
l.l = LevelInfo
l.Debugf(Log{Direction: DirServerToClient, Format: "test %s", Messages: []interface{}{"foo"}})
if b.String() != "" {
t.Error("Debug message was not expected to be logged")
}
}
func TestJSONInfof(t *testing.T) {
var b bytes.Buffer
l := NewJSON(&b, LevelInfo)
f := "test %s"
msg := "foo"
msg2 := "bar"
l.Infof(Log{Direction: DirServerToClient, Format: f, Messages: []interface{}{msg}})
exFrom := "server"
exTo := "client"
jl, err := unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg, jl.Message)
}
b.Reset()
l.Infof(Log{Direction: DirClientToServer, Format: f, Messages: []interface{}{msg2}})
exFrom = "client"
exTo = "server"
jl, err = unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg2) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg2, jl.Message)
}
b.Reset()
l.l = LevelWarn
l.Infof(Log{Direction: DirServerToClient, Format: "test %s", Messages: []interface{}{"foo"}})
if b.String() != "" {
t.Error("Info message was not expected to be logged")
}
}
func TestJSONWarnf(t *testing.T) {
var b bytes.Buffer
l := NewJSON(&b, LevelWarn)
f := "test %s"
msg := "foo"
msg2 := "bar"
l.Warnf(Log{Direction: DirServerToClient, Format: f, Messages: []interface{}{msg}})
exFrom := "server"
exTo := "client"
jl, err := unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg, jl.Message)
}
b.Reset()
l.Warnf(Log{Direction: DirClientToServer, Format: f, Messages: []interface{}{msg2}})
exFrom = "client"
exTo = "server"
jl, err = unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg2) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg2, jl.Message)
}
b.Reset()
l.l = LevelError
l.Warnf(Log{Direction: DirServerToClient, Format: "test %s", Messages: []interface{}{"foo"}})
if b.String() != "" {
t.Error("Warn message was not expected to be logged")
}
}
func TestJSONErrorf(t *testing.T) {
var b bytes.Buffer
l := NewJSON(&b, LevelError)
f := "test %s"
msg := "foo"
msg2 := "bar"
l.Errorf(Log{Direction: DirServerToClient, Format: f, Messages: []interface{}{msg}})
exFrom := "server"
exTo := "client"
jl, err := unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg, jl.Message)
}
b.Reset()
l.Errorf(Log{Direction: DirClientToServer, Format: f, Messages: []interface{}{msg2}})
exFrom = "client"
exTo = "server"
jl, err = unmarshalLog(b.Bytes())
if err != nil {
t.Errorf("Debugf() failed, unmarshal json log message failed: %s", err)
}
if jl.Direction.To != exTo {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exTo, jl.Direction.To)
}
if jl.Direction.From != exFrom {
t.Errorf("Debugf() failed, expected message to: %s, got: %s", exFrom, jl.Direction.From)
}
if jl.Message != fmt.Sprintf(f, msg2) {
t.Errorf("Debugf() failed, expected message: %s, got %s", msg2, jl.Message)
}
b.Reset()
l.l = -99
l.Errorf(Log{Direction: DirServerToClient, Format: "test %s", Messages: []interface{}{"foo"}})
if b.String() != "" {
t.Error("Error message was not expected to be logged")
}
}
func unmarshalLog(j []byte) (jsonLog, error) {
var jl jsonLog
if err := json.Unmarshal(j, &jl); err != nil {
return jl, err
}
return jl, nil
}