logger_test
API
logger_test
packageAPI reference for the logger_test
package.
Imports
(9)
F
function
TestCLEFSinkInformationOmitsLevel
Parameters
t
pkg/logger/clef_sink_test.go:13-41
func TestCLEFSinkInformationOmitsLevel(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewCLEFSink(buf)
err := sink.Log(logger.Entry{
Level: "info",
Time: time.Now().UTC(),
Msg: "service started",
Fields: map[string]interface{}{"port": 8080},
})
if err != nil {
t.Fatalf("Log() error = %v", err)
}
var m map[string]any
if err := json.Unmarshal([]byte(strings.TrimSpace(buf.String())), &m); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
if _, ok := m["@l"]; ok {
t.Fatalf("@l should be omitted for Information level, got %v", m["@l"])
}
if m["@m"] != "service started" {
t.Fatalf("@m = %v, want %q", m["@m"], "service started")
}
if m["port"] == nil {
t.Fatalf("structured field port missing from root level")
}
}
F
function
TestCLEFSinkLevelMapping
Parameters
t
pkg/logger/clef_sink_test.go:43-67
func TestCLEFSinkLevelMapping(t *testing.T)
{
cases := []struct {
in string
want string
}{
{"debug", "Debug"},
{"warn", "Warning"},
{"error", "Error"},
}
for _, tc := range cases {
buf := &bytes.Buffer{}
sink := logger.NewCLEFSink(buf)
_ = sink.Log(logger.Entry{Level: tc.in, Time: time.Now().UTC(), Msg: "msg"})
var m map[string]any
if err := json.Unmarshal([]byte(strings.TrimSpace(buf.String())), &m); err != nil {
t.Fatalf("level=%q: json.Unmarshal() error = %v", tc.in, err)
}
if m["@l"] != tc.want {
t.Fatalf("level=%q: @l = %v, want %q", tc.in, m["@l"], tc.want)
}
}
}
F
function
TestCLEFSinkFieldsFlattened
Parameters
t
pkg/logger/clef_sink_test.go:69-95
func TestCLEFSinkFieldsFlattened(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewCLEFSink(buf)
_ = sink.Log(logger.Entry{
Level: "info",
Time: time.Now().UTC(),
Msg: "request handled",
Fields: map[string]interface{}{
"request_id": "abc-123",
"status": 200,
},
})
var m map[string]any
if err := json.Unmarshal([]byte(strings.TrimSpace(buf.String())), &m); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
// Fields must be at root, not nested inside a "fields" key.
if _, nested := m["fields"]; nested {
t.Fatalf("fields should be flat at root, not nested under 'fields'")
}
if m["request_id"] != "abc-123" {
t.Fatalf("request_id = %v, want %q", m["request_id"], "abc-123")
}
}
F
function
TestCLEFSinkTimestampFormat
Parameters
t
pkg/logger/clef_sink_test.go:97-116
func TestCLEFSinkTimestampFormat(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewCLEFSink(buf)
ts := time.Date(2026, 3, 13, 9, 0, 0, 0, time.UTC)
_ = sink.Log(logger.Entry{Level: "info", Time: ts, Msg: "ts check"})
var m map[string]any
if err := json.Unmarshal([]byte(strings.TrimSpace(buf.String())), &m); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
got, ok := m["@t"].(string)
if !ok {
t.Fatalf("@t is not a string: %v", m["@t"])
}
if !strings.HasPrefix(got, "2026-03-13T09:00:00") {
t.Fatalf("@t = %q, want RFC3339Nano starting with 2026-03-13T09:00:00", got)
}
}
F
function
TestCLEFSinkViaLogger
Parameters
t
pkg/logger/clef_sink_test.go:118-137
func TestCLEFSinkViaLogger(t *testing.T)
{
buf := &bytes.Buffer{}
// Default logger has ConsoleSink; replace with CLEFSink only.
lg := logger.New(logger.WithSink(logger.NewCLEFSink(buf)))
lg.Warn("disk space low", logger.Field{Key: "free_gb", Value: 2})
var m map[string]any
if err := json.Unmarshal([]byte(strings.TrimSpace(buf.String())), &m); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
if m["@l"] != "Warning" {
t.Fatalf("@l = %v, want Warning", m["@l"])
}
if m["@m"] != "disk space low" {
t.Fatalf("@m = %v, want 'disk space low'", m["@m"])
}
if m["free_gb"] == nil {
t.Fatalf("free_gb missing from CLEF output")
}
}
F
function
TestConsoleSinkJSON
Parameters
t
pkg/logger/logger_test.go:16-40
func TestConsoleSinkJSON(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewConsoleSink(buf)
lg := logger.New(logger.WithSink(sink), logger.WithLevel(logger.DebugLevel))
lg.Info("hello", logger.Field{Key: "k", Value: "v"})
line, err := buf.ReadString('\n')
if err != nil {
t.Fatalf("ReadString() error = %v", err)
}
var entry logger.Entry
if err := json.Unmarshal([]byte(strings.TrimSpace(line)), &entry); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
if entry.Msg != "hello" {
t.Fatalf("entry.Msg = %q, want %q", entry.Msg, "hello")
}
if entry.Level != "info" {
t.Fatalf("entry.Level = %q, want %q", entry.Level, "info")
}
if got, ok := entry.Fields["k"]; !ok || got != "v" {
t.Fatalf("entry.Fields = %v, want key k=v", entry.Fields)
}
}
F
function
TestLevelFiltering
Parameters
t
pkg/logger/logger_test.go:42-55
func TestLevelFiltering(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewConsoleSink(buf)
lg := logger.New(logger.WithSink(sink), logger.WithLevel(logger.WarnLevel))
lg.Info("should be filtered")
if buf.Len() != 0 {
t.Fatalf("buffer length = %d, want 0", buf.Len())
}
lg.Error("should appear")
if buf.Len() == 0 {
t.Fatalf("buffer length = 0, want > 0")
}
}
F
function
TestWithBindsContextFields
Parameters
t
pkg/logger/logger_test.go:57-80
func TestWithBindsContextFields(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewConsoleSink(buf)
lg := logger.New(logger.WithSink(sink), logger.WithFields(logger.Field{Key: "service", Value: "api"}))
requestLogger := lg.With(logger.Field{Key: "request_id", Value: "abc"})
requestLogger.Info("serving")
line, err := buf.ReadString('\n')
if err != nil {
t.Fatalf("ReadString() error = %v", err)
}
var entry logger.Entry
if err := json.Unmarshal([]byte(strings.TrimSpace(line)), &entry); err != nil {
t.Fatalf("json.Unmarshal() error = %v", err)
}
if entry.Fields["service"] != "api" {
t.Fatalf("service field = %v, want api", entry.Fields["service"])
}
if entry.Fields["request_id"] != "abc" {
t.Fatalf("request_id field = %v, want abc", entry.Fields["request_id"])
}
}
F
function
TestPrometheusSinkTracksCounts
Parameters
t
pkg/logger/logger_test.go:82-102
func TestPrometheusSinkTracksCounts(t *testing.T)
{
sink := logger.NewPrometheusSink(logger.InfoLevel, "go_logger")
if err := sink.Log(logger.Entry{Level: "debug", Time: time.Now(), Msg: "ignored"}); err != nil {
t.Fatalf("Log() error = %v", err)
}
if err := sink.Log(logger.Entry{Level: "error", Time: time.Now(), Msg: "counted"}); err != nil {
t.Fatalf("Log() error = %v", err)
}
rr := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/metrics", nil)
sink.Handler().ServeHTTP(rr, req)
body := rr.Body.String()
if strings.Contains(body, "debug") {
t.Fatalf("metrics body unexpectedly contains debug counter: %q", body)
}
if !strings.Contains(body, "level=\"error\"") {
t.Fatalf("metrics body = %q, want error counter", body)
}
}
F
function
TestNewTelegramSinkFromEnv
Parameters
t
pkg/logger/logger_test.go:104-115
func TestNewTelegramSinkFromEnv(t *testing.T)
{
t.Setenv("TELEGRAM_BOT_TOKEN", "token")
t.Setenv("TELEGRAM_CHAT_ID", "chat")
sink, err := logger.NewTelegramSinkFromEnv(logger.ErrorLevel)
if err != nil {
t.Fatalf("NewTelegramSinkFromEnv() error = %v", err)
}
if sink == nil {
t.Fatalf("NewTelegramSinkFromEnv() = nil, want non-nil")
}
}
F
function
TestRotatingFileSinkWritesJSONLines
Parameters
t
pkg/logger/logger_test.go:117-144
func TestRotatingFileSinkWritesJSONLines(t *testing.T)
{
path := filepath.Join(t.TempDir(), "app.log")
sink, err := logger.NewRotatingFileSink(path, logger.RotatingFileOptions{MaxSizeMB: 1})
if err != nil {
t.Fatalf("NewRotatingFileSink() error = %v", err)
}
defer sink.Close()
entry := logger.Entry{
Level: "info",
Time: time.Now().UTC(),
Msg: "written-to-file",
Fields: map[string]interface{}{
"service": "api",
},
}
if err := sink.Log(entry); err != nil {
t.Fatalf("Log() error = %v", err)
}
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("os.ReadFile() error = %v", err)
}
if !strings.Contains(string(content), "\"msg\":\"written-to-file\"") {
t.Fatalf("log file content = %q, want serialized entry", string(content))
}
}
F
function
TestRotatingFileSinkRotates
Parameters
t
pkg/logger/logger_test.go:146-168
func TestRotatingFileSinkRotates(t *testing.T)
{
path := filepath.Join(t.TempDir(), "app.log")
sink, err := logger.NewRotatingFileSink(path, logger.RotatingFileOptions{MaxSizeMB: 1, MaxBackups: 2})
if err != nil {
t.Fatalf("NewRotatingFileSink() error = %v", err)
}
defer sink.Close()
largeMessage := strings.Repeat("x", 600*1024)
for i := 0; i < 3; i++ {
if err := sink.Log(logger.Entry{Level: "info", Time: time.Now().UTC(), Msg: largeMessage}); err != nil {
t.Fatalf("Log() iteration %d error = %v", i, err)
}
}
matches, err := filepath.Glob(filepath.Join(filepath.Dir(path), "app*.log*"))
if err != nil {
t.Fatalf("filepath.Glob() error = %v", err)
}
if len(matches) < 2 {
t.Fatalf("rotated files = %v, want at least 2 files", matches)
}
}
F
function
TestWithoutDefaultSink
Parameters
t
pkg/logger/logger_test.go:170-178
func TestWithoutDefaultSink(t *testing.T)
{
buf := &bytes.Buffer{}
sink := logger.NewConsoleSink(buf)
lg := logger.New(logger.WithoutDefaultSink(), logger.WithSink(sink))
lg.Info("hello")
if buf.Len() == 0 {
t.Fatal("expected custom sink to receive output, got empty buffer")
}
}