feat: backend service
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
// Package logging configures the backend structured logger.
|
||||
package logging
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"galaxy/backend/internal/config"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// New constructs the process-wide JSON logger from cfg.
|
||||
func New(cfg config.LoggingConfig) (*zap.Logger, error) {
|
||||
level := zap.NewAtomicLevel()
|
||||
if err := level.UnmarshalText([]byte(strings.TrimSpace(cfg.Level))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zapCfg := zap.NewProductionConfig()
|
||||
zapCfg.Level = level
|
||||
zapCfg.Sampling = nil
|
||||
zapCfg.Encoding = "json"
|
||||
zapCfg.EncoderConfig.TimeKey = "timestamp"
|
||||
zapCfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
zapCfg.OutputPaths = []string{"stdout"}
|
||||
zapCfg.ErrorOutputPaths = []string{"stderr"}
|
||||
|
||||
return zapCfg.Build()
|
||||
}
|
||||
|
||||
// Sync flushes logger and ignores the benign stdout or stderr sync errors
|
||||
// commonly returned by containerized or redirected process outputs.
|
||||
func Sync(logger *zap.Logger) error {
|
||||
if logger == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := logger.Sync()
|
||||
if err == nil || isIgnorableSyncError(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func isIgnorableSyncError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
message := strings.ToLower(err.Error())
|
||||
switch {
|
||||
case strings.Contains(message, "invalid argument"):
|
||||
return true
|
||||
case strings.Contains(message, "bad file descriptor"):
|
||||
return true
|
||||
case strings.Contains(message, "inappropriate ioctl for device"):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user