Files
wehub-resource-sync 75f3dd141c
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CI and Release / lint-frontend (push) Has been cancelled
CI and Release / dockerfile-scan (push) Has been cancelled
CI and Release / test-frontend (push) Has been cancelled
CI and Release / lint-verification-agent (push) Has been cancelled
CI and Release / test-verification-agent (push) Has been cancelled
CI and Release / e2e-verification-agent (push) Has been cancelled
CI and Release / test-backend (push) Has been cancelled
CI and Release / build-dev-image (push) Has been cancelled
CI and Release / push-dev-image (push) Has been cancelled
CI and Release / build-image (push) Has been cancelled
CI and Release / build-verification-image (push) Has been cancelled
CI and Release / determine-version (push) Has been cancelled
CI and Release / push-image (push) Has been cancelled
CI and Release / push-verification-image (12) (push) Has been cancelled
CI and Release / lint-backend (push) Has been cancelled
CI and Release / push-verification-image (17) (push) Has been cancelled
CI and Release / push-verification-image (18) (push) Has been cancelled
CI and Release / release (push) Has been cancelled
CI and Release / publish-helm-chart (push) Has been cancelled
CI and Release / push-verification-image (13) (push) Has been cancelled
CI and Release / push-verification-image (14) (push) Has been cancelled
CI and Release / push-verification-image (15) (push) Has been cancelled
CI and Release / push-verification-image (16) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:11:07 +08:00

123 lines
2.8 KiB
Go

package logger
import (
"fmt"
"log/slog"
"os"
"path/filepath"
"sync"
"time"
"github.com/joho/godotenv"
)
var (
loggerInstance *slog.Logger
victoriaLogsWriter *VictoriaLogsWriter
)
var initLogger = sync.OnceFunc(func() {
// Create stdout handler
stdoutHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey {
a.Value = slog.StringValue(time.Now().Format("2006/01/02 15:04:05"))
}
if a.Key == slog.LevelKey {
return slog.Attr{}
}
return a
},
})
// Try to initialize VictoriaLogs writer if configured
// Note: This will be called before config is fully loaded in some cases,
// so we need to handle that gracefully
victoriaLogsWriter = tryInitVictoriaLogs()
// Create multi-handler
multiHandler := NewMultiHandler(stdoutHandler, victoriaLogsWriter)
loggerInstance = slog.New(multiHandler)
loggerInstance.Info("Text structured logger initialized")
if victoriaLogsWriter != nil {
loggerInstance.Info("VictoriaLogs enabled")
} else {
loggerInstance.Info("VictoriaLogs disabled")
}
})
// GetLogger returns a singleton slog.Logger that logs to the console
func GetLogger() *slog.Logger {
initLogger()
return loggerInstance
}
// ShutdownVictoriaLogs gracefully shuts down the VictoriaLogs writer
var ShutdownVictoriaLogs = sync.OnceFunc(func() {
if victoriaLogsWriter != nil {
victoriaLogsWriter.Shutdown(5 * time.Second)
}
})
func tryInitVictoriaLogs() *VictoriaLogsWriter {
// Ensure .env is loaded before reading environment variables
ensureEnvLoaded()
// Try to get config - this may fail early in startup
url := getVictoriaLogsURL()
username := getVictoriaLogsUsername()
password := getVictoriaLogsPassword()
if url == "" {
fmt.Println("VictoriaLogs URL is not set")
return nil
}
return NewVictoriaLogsWriter(url, username, password)
}
var ensureEnvLoaded = sync.OnceFunc(func() {
cwd, err := os.Getwd()
if err != nil {
fmt.Printf("Warning: could not get current working directory: %v\n", err)
cwd = "."
}
backendRoot := cwd
for {
if _, err := os.Stat(filepath.Join(backendRoot, "go.mod")); err == nil {
break
}
parent := filepath.Dir(backendRoot)
if parent == backendRoot {
break
}
backendRoot = parent
}
envPath := filepath.Join(filepath.Dir(backendRoot), ".env")
if err := godotenv.Load(envPath); err == nil {
fmt.Printf("Logger: loaded .env from %s\n", envPath)
return
}
fmt.Println("Logger: .env file not found at repo root, using existing environment variables")
})
func getVictoriaLogsURL() string {
return os.Getenv("VICTORIA_LOGS_URL")
}
func getVictoriaLogsUsername() string {
return os.Getenv("VICTORIA_LOGS_USERNAME")
}
func getVictoriaLogsPassword() string {
return os.Getenv("VICTORIA_LOGS_PASSWORD")
}