fix: logging module
This commit is contained in:
7
go.mod
7
go.mod
@@ -6,6 +6,13 @@ toolchain go1.23.7
|
||||
|
||||
require golang.org/x/crypto v0.36.0
|
||||
|
||||
require (
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/rs/zerolog v1.33.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
|
||||
16
go.sum
16
go.sum
@@ -1,8 +1,24 @@
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
||||
150
log/log.go
Normal file
150
log/log.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package logpackage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type LoggerConfig struct {
|
||||
Level string `yaml:"level"`
|
||||
FilePath string `yaml:"file_path"`
|
||||
MaxSize int `yaml:"max_size"`
|
||||
MaxBackups int `yaml:"max_backups"`
|
||||
MaxAge int `yaml:"max_age"`
|
||||
ContextKeys []string `yaml:"context_keys"`
|
||||
}
|
||||
|
||||
var (
|
||||
logger zerolog.Logger
|
||||
cfg LoggerConfig
|
||||
once sync.Once
|
||||
|
||||
getConfigPath = func() (string, error) {
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("failed to get runtime caller")
|
||||
}
|
||||
dir := filepath.Dir(file)
|
||||
return filepath.Join(dir, "log.yaml"), nil
|
||||
}
|
||||
)
|
||||
|
||||
func loadConfig() (LoggerConfig, error) {
|
||||
var config LoggerConfig
|
||||
|
||||
configPath, err := getConfigPath()
|
||||
if err != nil {
|
||||
return config, fmt.Errorf("error finding config path: %w", err)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return config, fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return config, fmt.Errorf("failed to parse YAML: %w", err)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func InitLogger(configs ...LoggerConfig) {
|
||||
once.Do(func() {
|
||||
var err error
|
||||
|
||||
if len(configs) > 0 {
|
||||
cfg = configs[0]
|
||||
} else {
|
||||
cfg, err = loadConfig()
|
||||
if err != nil {
|
||||
fmt.Println("Logger initialization failed:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
level, err := zerolog.ParseLevel(cfg.Level)
|
||||
if err != nil {
|
||||
level = zerolog.InfoLevel
|
||||
}
|
||||
|
||||
zerolog.SetGlobalLevel(level)
|
||||
zerolog.TimeFieldFormat = time.RFC3339
|
||||
|
||||
logWriter := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}
|
||||
fileWriter := &lumberjack.Logger{
|
||||
Filename: cfg.FilePath,
|
||||
MaxSize: cfg.MaxSize,
|
||||
MaxBackups: cfg.MaxBackups,
|
||||
MaxAge: cfg.MaxAge,
|
||||
}
|
||||
|
||||
multi := zerolog.MultiLevelWriter(logWriter, fileWriter)
|
||||
logger = zerolog.New(multi).With().Timestamp().Logger()
|
||||
})
|
||||
}
|
||||
|
||||
func Debug(ctx context.Context, msg string) {
|
||||
logEvent(ctx, logger.Debug(), msg)
|
||||
}
|
||||
|
||||
func Debugf(ctx context.Context, format string, v ...any) {
|
||||
logEvent(ctx, logger.Debug(), fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Info(ctx context.Context, msg string) {
|
||||
logEvent(ctx, logger.Info(), msg)
|
||||
}
|
||||
|
||||
func Infof(ctx context.Context, format string, v ...any) {
|
||||
logEvent(ctx, logger.Info(), fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Warn(ctx context.Context, msg string) {
|
||||
logEvent(ctx, logger.Warn(), msg)
|
||||
}
|
||||
|
||||
func Warnf(ctx context.Context, format string, v ...any) {
|
||||
logEvent(ctx, logger.Warn(), fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Error(ctx context.Context, err error, msg string) {
|
||||
logEvent(ctx, logger.Error().Err(err), msg)
|
||||
}
|
||||
|
||||
func Errorf(ctx context.Context, err error, format string, v ...any) {
|
||||
logEvent(ctx, logger.Error().Err(err), fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
var ExitFunc = func(code int) {
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func Fatal(ctx context.Context, msg string) {
|
||||
logEvent(ctx, logger.Error(), msg)
|
||||
ExitFunc(1)
|
||||
}
|
||||
|
||||
func Fatalf(ctx context.Context, format string, v ...any) {
|
||||
logEvent(ctx, logger.Fatal(), fmt.Sprintf(format, v...))
|
||||
ExitFunc(1)
|
||||
}
|
||||
|
||||
func logEvent(ctx context.Context, event *zerolog.Event, msg string) {
|
||||
for _, key := range cfg.ContextKeys {
|
||||
if val, ok := ctx.Value(key).(string); ok && val != "" {
|
||||
event.Str(key, val)
|
||||
}
|
||||
}
|
||||
event.Msg(msg)
|
||||
}
|
||||
12
log/log.yaml
Normal file
12
log/log.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
level: info
|
||||
destinations:
|
||||
- type: stdout
|
||||
- type: file
|
||||
config:
|
||||
path: logs/app.log
|
||||
maxSize: "500"
|
||||
maxBackups: "15"
|
||||
maxAge: "30"
|
||||
context_keys:
|
||||
- requestId
|
||||
- userId
|
||||
391
log/logpackage_test.go
Normal file
391
log/logpackage_test.go
Normal file
@@ -0,0 +1,391 @@
|
||||
package logpackage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func setupTest(t *testing.T) string {
|
||||
once = sync.Once{}
|
||||
|
||||
tempDir, err := os.MkdirTemp("", "logger-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
|
||||
return tempDir
|
||||
}
|
||||
|
||||
func TestInitLoggerWithValidConfig(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testLogPath := filepath.Join(tempDir, "test.log")
|
||||
|
||||
InitLogger(LoggerConfig{
|
||||
Level: "debug",
|
||||
FilePath: testLogPath,
|
||||
MaxSize: 10,
|
||||
MaxBackups: 3,
|
||||
MaxAge: 7,
|
||||
ContextKeys: []string{"request_id", "user_id"},
|
||||
})
|
||||
|
||||
if logger.GetLevel() == zerolog.Disabled {
|
||||
t.Error("Logger was not initialized")
|
||||
}
|
||||
|
||||
ctx := context.WithValue(context.Background(), "request_id", "test-123")
|
||||
Debug(ctx, "debug message")
|
||||
Info(ctx, "info message")
|
||||
Warn(ctx, "warning message")
|
||||
Error(ctx, errors.New("test error"), "error message")
|
||||
|
||||
if _, err := os.Stat(testLogPath); os.IsNotExist(err) {
|
||||
t.Errorf("Log file was not created at %s", testLogPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitLoggerWithInvalidLevel(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testLogPath := filepath.Join(tempDir, "test.log")
|
||||
|
||||
InitLogger(LoggerConfig{
|
||||
Level: "invalid_level",
|
||||
FilePath: testLogPath,
|
||||
MaxSize: 10,
|
||||
MaxBackups: 3,
|
||||
MaxAge: 7,
|
||||
ContextKeys: []string{"request_id"},
|
||||
})
|
||||
|
||||
if logger.GetLevel() == zerolog.Disabled {
|
||||
t.Error("Logger was not initialized")
|
||||
}
|
||||
|
||||
ctx := context.WithValue(context.Background(), "request_id", "test-123")
|
||||
Info(ctx, "info message")
|
||||
|
||||
if _, err := os.Stat(testLogPath); os.IsNotExist(err) {
|
||||
t.Errorf("Log file was not created at %s", testLogPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigFromFile(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
configPath := filepath.Join(tempDir, "log.yaml")
|
||||
configContent := `level: debug
|
||||
file_path: /tmp/test.log
|
||||
max_size: 10
|
||||
max_backups: 3
|
||||
max_age: 7
|
||||
context_keys:
|
||||
- request_id
|
||||
- user_id`
|
||||
|
||||
err := os.WriteFile(configPath, []byte(configContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write config file: %v", err)
|
||||
}
|
||||
|
||||
originalGetConfigPath := getConfigPath
|
||||
defer func() { getConfigPath = originalGetConfigPath }()
|
||||
getConfigPath = func() (string, error) {
|
||||
return configPath, nil
|
||||
}
|
||||
|
||||
config, err := loadConfig()
|
||||
if err != nil {
|
||||
t.Errorf("loadConfig() error = %v", err)
|
||||
}
|
||||
|
||||
if config.Level != "debug" {
|
||||
t.Errorf("Expected level 'debug', got '%s'", config.Level)
|
||||
}
|
||||
if config.FilePath != "/tmp/test.log" {
|
||||
t.Errorf("Expected file_path '/tmp/test.log', got '%s'", config.FilePath)
|
||||
}
|
||||
if len(config.ContextKeys) != 2 {
|
||||
t.Errorf("Expected 2 context keys, got %d", len(config.ContextKeys))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigNonExistent(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
configPath := filepath.Join(tempDir, "non-existent.yaml")
|
||||
|
||||
originalGetConfigPath := getConfigPath
|
||||
defer func() { getConfigPath = originalGetConfigPath }()
|
||||
getConfigPath = func() (string, error) {
|
||||
return configPath, nil
|
||||
}
|
||||
|
||||
_, err := loadConfig()
|
||||
if err == nil {
|
||||
t.Error("Expected error for non-existent config file, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigInvalidYAML(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
configPath := filepath.Join(tempDir, "invalid.yaml")
|
||||
configContent := `level: debug
|
||||
file_path: /tmp/test.log
|
||||
max_size: invalid
|
||||
max_backups: 3`
|
||||
|
||||
err := os.WriteFile(configPath, []byte(configContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write config file: %v", err)
|
||||
}
|
||||
|
||||
originalGetConfigPath := getConfigPath
|
||||
defer func() { getConfigPath = originalGetConfigPath }()
|
||||
getConfigPath = func() (string, error) {
|
||||
return configPath, nil
|
||||
}
|
||||
|
||||
_, err = loadConfig()
|
||||
if err == nil {
|
||||
t.Error("Expected error for invalid YAML, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFatal(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testLogPath := filepath.Join(tempDir, "fatal.log")
|
||||
|
||||
originalExitFunc := ExitFunc
|
||||
defer func() { ExitFunc = originalExitFunc }()
|
||||
|
||||
var exitCalled bool
|
||||
var exitCode int
|
||||
ExitFunc = func(code int) {
|
||||
exitCalled = true
|
||||
exitCode = code
|
||||
|
||||
}
|
||||
|
||||
InitLogger(LoggerConfig{
|
||||
Level: "debug",
|
||||
FilePath: testLogPath,
|
||||
MaxSize: 10,
|
||||
MaxBackups: 3,
|
||||
MaxAge: 7,
|
||||
ContextKeys: []string{"request_id"},
|
||||
})
|
||||
|
||||
ctx := context.WithValue(context.Background(), "request_id", "test-fatal")
|
||||
Fatal(ctx, "fatal message")
|
||||
|
||||
if !exitCalled {
|
||||
t.Error("ExitFunc was not called")
|
||||
}
|
||||
if exitCode != 1 {
|
||||
t.Errorf("Expected exit code 1, got %d", exitCode)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(testLogPath); os.IsNotExist(err) {
|
||||
t.Errorf("Log file was not created at %s", testLogPath)
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(testLogPath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read log file: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(content), "fatal message") {
|
||||
t.Error("Log file does not contain fatal message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoggingWithContext(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testLogPath := filepath.Join(tempDir, "context.log")
|
||||
|
||||
// Initialize logger with context keys
|
||||
InitLogger(LoggerConfig{
|
||||
Level: "debug",
|
||||
FilePath: testLogPath,
|
||||
MaxSize: 10,
|
||||
MaxBackups: 3,
|
||||
MaxAge: 7,
|
||||
ContextKeys: []string{"request_id", "user_id", "session_id"},
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, "request_id", "req-123")
|
||||
ctx = context.WithValue(ctx, "user_id", "user-456")
|
||||
Info(ctx, "message with context")
|
||||
|
||||
if _, err := os.Stat(testLogPath); os.IsNotExist(err) {
|
||||
t.Errorf("Log file was not created at %s", testLogPath)
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(testLogPath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read log file: %v", err)
|
||||
}
|
||||
|
||||
contentStr := string(content)
|
||||
if !strings.Contains(contentStr, "req-123") {
|
||||
t.Error("Log file does not contain request_id")
|
||||
}
|
||||
if !strings.Contains(contentStr, "user-456") {
|
||||
t.Error("Log file does not contain user_id")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormattedLogging(t *testing.T) {
|
||||
once = sync.Once{}
|
||||
|
||||
tempDir, err := os.MkdirTemp("", "logger-format-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testLogPath := filepath.Join(tempDir, "formatted.log")
|
||||
|
||||
InitLogger(LoggerConfig{
|
||||
Level: "debug",
|
||||
FilePath: testLogPath,
|
||||
MaxSize: 10,
|
||||
MaxBackups: 3,
|
||||
MaxAge: 7,
|
||||
ContextKeys: []string{"request_id"},
|
||||
})
|
||||
|
||||
ctx := context.WithValue(context.Background(), "request_id", "format-test-123")
|
||||
|
||||
testValues := []struct {
|
||||
name string
|
||||
number int
|
||||
text string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "debug",
|
||||
number: 42,
|
||||
text: "formatted debug",
|
||||
expected: "formatted debug message #42",
|
||||
},
|
||||
{
|
||||
name: "info",
|
||||
number: 100,
|
||||
text: "formatted info",
|
||||
expected: "formatted info message #100",
|
||||
},
|
||||
{
|
||||
name: "warn",
|
||||
number: 200,
|
||||
text: "formatted warning",
|
||||
expected: "formatted warning message #200",
|
||||
},
|
||||
{
|
||||
name: "error",
|
||||
number: 500,
|
||||
text: "formatted error",
|
||||
expected: "formatted error message #500",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tv := range testValues {
|
||||
t.Run(tv.name+"f", func(t *testing.T) {
|
||||
format := "%s message #%d"
|
||||
|
||||
switch tv.name {
|
||||
case "debug":
|
||||
Debugf(ctx, format, tv.text, tv.number)
|
||||
case "info":
|
||||
Infof(ctx, format, tv.text, tv.number)
|
||||
case "warn":
|
||||
Warnf(ctx, format, tv.text, tv.number)
|
||||
case "error":
|
||||
testErr := errors.New("test error")
|
||||
Errorf(ctx, testErr, format, tv.text, tv.number)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoggingWithNonStringContext(t *testing.T) {
|
||||
tempDir := setupTest(t)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
testLogPath := filepath.Join(tempDir, "non-string.log")
|
||||
|
||||
InitLogger(LoggerConfig{
|
||||
Level: "debug",
|
||||
FilePath: testLogPath,
|
||||
MaxSize: 10,
|
||||
MaxBackups: 3,
|
||||
MaxAge: 7,
|
||||
ContextKeys: []string{"request_id", "count"},
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, "request_id", "req-123")
|
||||
ctx = context.WithValue(ctx, "count", 42)
|
||||
|
||||
Info(ctx, "message with non-string context")
|
||||
|
||||
if _, err := os.Stat(testLogPath); os.IsNotExist(err) {
|
||||
t.Errorf("Log file was not created at %s", testLogPath)
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(testLogPath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read log file: %v", err)
|
||||
}
|
||||
|
||||
contentStr := string(content)
|
||||
if !strings.Contains(contentStr, "req-123") {
|
||||
t.Error("Log file does not contain request_id")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetConfigPath(t *testing.T) {
|
||||
path, err := getConfigPath()
|
||||
if err != nil {
|
||||
t.Errorf("getConfigPath() error = %v", err)
|
||||
}
|
||||
if path == "" {
|
||||
t.Error("getConfigPath() returned empty path")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetConfigPathError(t *testing.T) {
|
||||
|
||||
originalGetConfigPath := getConfigPath
|
||||
defer func() { getConfigPath = originalGetConfigPath }()
|
||||
|
||||
expectedErr := errors.New("runtime caller error")
|
||||
getConfigPath = func() (string, error) {
|
||||
return "", expectedErr
|
||||
}
|
||||
|
||||
once = sync.Once{}
|
||||
InitLogger()
|
||||
ctx := context.Background()
|
||||
Info(ctx, "info after config failure")
|
||||
}
|
||||
Reference in New Issue
Block a user