Update logger configuration for development environment, enhancing logging structure with zap and lumberjack settings. Refactor logging utility to improve configuration file handling and add error management. Modify integration tests to utilize the new logger setup and adjust test payloads for consistency.

This commit is contained in:
windyboy
2025-11-15 17:42:10 +08:00
parent 53208997e8
commit dccff366d2
3 changed files with 85 additions and 13 deletions
+33
View File
@@ -1,3 +1,36 @@
{
"zapConfig": {
"level": "info",
"development": true,
"encoding": "json",
"encoderConfig": {
"messageKey": "msg",
"levelKey": "level",
"timeKey": "ts",
"nameKey": "logger",
"callerKey": "caller",
"stacktraceKey": "stacktrace",
"lineEnding": "",
"levelEncoder": "lowercase",
"timeEncoder": "iso8601",
"durationEncoder": "string",
"callerEncoder": "short"
},
"outputPaths": [
"stdout"
],
"errorOutputPaths": [
"stderr"
]
},
"lumberjackConfig": {
"filename": "./logs/caatsm-dev.log",
"maxSize": 50,
"maxBackups": 5,
"maxAge": 14,
"compress": false
}
}
{
"zapConfig": {
"level": "debug",
+36 -4
View File
@@ -2,8 +2,12 @@ package utils
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
@@ -12,7 +16,7 @@ import (
const (
TestConfigFileName = "./configs/logger.test.json"
ProdConfigFileName = ".configs/logger.json"
ProdConfigFileName = "./configs/logger.json"
DevelopmentConfigFileName = "./configs/logger.dev.json"
EnvTest = "test"
EnvProd = "prod"
@@ -33,10 +37,20 @@ type LumberjackConfig struct {
}
var (
sugar *zap.SugaredLogger
log *zap.Logger
sugar *zap.SugaredLogger
log *zap.Logger
rootDir = detectRootDir()
)
func detectRootDir() string {
_, file, _, ok := runtime.Caller(0)
if !ok {
return "."
}
// pkg/utils/log.go -> project root
return filepath.Clean(filepath.Join(filepath.Dir(file), "..", ".."))
}
func load() {
if log == nil {
env := getEnv()
@@ -103,7 +117,7 @@ func getConfigFile(env string) string {
}
func loadConfig(configFile string) (LoggerConfig, error) {
file, err := os.Open(configFile)
file, err := openConfigFile(configFile)
if err != nil {
return LoggerConfig{}, fmt.Errorf("error opening file: %v", err)
}
@@ -123,6 +137,24 @@ func GetLogger() *zap.SugaredLogger {
return sugar
}
func openConfigFile(configFile string) (*os.File, error) {
candidates := []string{
configFile,
filepath.Join(rootDir, strings.TrimPrefix(configFile, "./")),
}
for _, candidate := range candidates {
if candidate == "" {
continue
}
if f, err := os.Open(candidate); err == nil {
return f, nil
} else if !errors.Is(err, os.ErrNotExist) {
return nil, err
}
}
return nil, fmt.Errorf("error opening file: %v", configFile)
}
func parseLogLevel(level string) zapcore.Level {
switch level {
case "debug":
@@ -14,6 +14,7 @@ import (
"caatsm/internal/app"
"caatsm/internal/domain"
"caatsm/internal/infra/config"
loginfra "caatsm/internal/infra/log"
natsinfra "caatsm/internal/infra/nats"
postgresinfra "caatsm/internal/infra/postgres"
@@ -21,7 +22,6 @@ import (
"github.com/nats-io/nats.go"
tc "github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
"go.uber.org/zap"
)
func TestJetStreamToTimescaleFlow(t *testing.T) {
@@ -43,7 +43,11 @@ func TestJetStreamToTimescaleFlow(t *testing.T) {
}()
cfg := buildTestConfig(natsURL, pgURL)
logger := zap.NewNop()
logger, err := loginfra.ProvideLogger(cfg)
if err != nil {
t.Fatalf("failed to init logger: %v", err)
}
defer logger.Sync()
pool, err := postgresinfra.ProvideDB(cfg)
if err != nil {
@@ -99,10 +103,10 @@ func TestJetStreamToTimescaleFlow(t *testing.T) {
}()
// Publish a message to the input subject.
payload := []byte(`ZCZC ARR1234 150631
payload := []byte(`ZCZC TMQ2526 141605
FF ZBTJZPZX
150630 ZBACZQZX
(ARR-CCA1234-A1234-ZBTJ1500-ZGGG0135)
141604 ZBACZQZX
(ARR-JAE7433/A0132-RKSI-ZBTJ1604)
NNNN`)
msg := nats.NewMsg(cfg.EffectiveSubscriptionTopic())
@@ -125,9 +129,12 @@ NNNN`)
var status string
err := pool.QueryRow(ctx, `
SELECT status FROM aviation.telegrams WHERE message_id = $1 LIMIT 1
`, "ARR1234").Scan(&status)
if err == nil && status == string(domain.MessageStatusParsed) {
return
`, "TMQ2526").Scan(&status)
if err == nil {
if status == string(domain.MessageStatusParsed) {
return
}
t.Logf("message persisted with status=%s, waiting for parsed", status)
}
time.Sleep(500 * time.Millisecond)
@@ -237,7 +244,7 @@ func buildTestConfig(natsURL, pgURL string) *config.Config {
MonitorInterval: time.Second,
},
Log: config.LogConfig{
Level: "error",
Level: "debug",
Format: "json",
},
Publisher: config.PublisherConfig{