diff --git a/internal/config/state.go b/internal/config/state.go index 63712dae..d854d6a9 100644 --- a/internal/config/state.go +++ b/internal/config/state.go @@ -55,7 +55,7 @@ func NewState() config.State { entrypoint: entrypoint.NewEntrypoint(), task: task.RootTask("config", false), tmpLogBuf: tmpLogBuf, - tmpLog: logging.NewLogger(tmpLogBuf), + tmpLog: logging.NewLoggerWithFixedLevel(zerolog.InfoLevel, tmpLogBuf), } } diff --git a/internal/logging/logging.go b/internal/logging/logging.go index 1a9fa85f..b02214ae 100644 --- a/internal/logging/logging.go +++ b/internal/logging/logging.go @@ -8,11 +8,19 @@ import ( "github.com/rs/zerolog" "github.com/yusing/godoxy/internal/common" - strutils "github.com/yusing/goutils/strings" zerologlog "github.com/rs/zerolog/log" ) +func InitLogger(out ...io.Writer) { + logger = NewLogger(out...) + log.SetOutput(logger) + log.SetPrefix("") + log.SetFlags(0) + zerolog.TimeFieldFormat = timeFmt + zerologlog.Logger = logger +} + var ( logger zerolog.Logger timeFmt string @@ -38,54 +46,62 @@ func init() { } func fmtMessage(msg string) string { - lines := strutils.SplitRune(msg, '\n') - if len(lines) == 1 { + nLines := strings.Count(msg, "\n") + if nLines == 0 { return msg } - for i := 1; i < len(lines); i++ { - lines[i] = prefix + lines[i] + + var sb strings.Builder + sb.Grow(len(msg) + nLines*len(prefix)) + + // write first line unindented + idx := strings.IndexByte(msg, '\n') + sb.WriteString(msg[:idx]) + sb.WriteByte('\n') + msg = msg[idx+1:] + + // write remaining lines indented + for line := range strings.Lines(msg) { + sb.WriteString(prefix) + sb.WriteString(line) } - return strutils.JoinRune(lines, '\n') + return sb.String() +} + +func multiLevelWriter(out ...io.Writer) io.Writer { + if len(out) == 0 { + return os.Stdout + } + if len(out) == 1 { + return out[0] + } + return io.MultiWriter(out...) } func NewLogger(out ...io.Writer) zerolog.Logger { - writer := zerolog.ConsoleWriter{ - Out: zerolog.MultiLevelWriter(out...), - TimeFormat: timeFmt, - FormatMessage: func(msgI interface{}) string { // pad spaces for each line - return fmtMessage(msgI.(string)) - }, - } - return zerolog.New( - writer, - ).Level(level).With().Timestamp().Logger() -} - -func NewLoggerWithFixedLevel(level zerolog.Level, out ...io.Writer) zerolog.Logger { - levelStr := level.String() - writer := zerolog.ConsoleWriter{ - Out: zerolog.MultiLevelWriter(out...), - TimeFormat: timeFmt, - FormatMessage: func(msgI interface{}) string { // pad spaces for each line + writer := zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) { + w.Out = multiLevelWriter(out...) + w.TimeFormat = timeFmt + w.FormatMessage = func(msgI any) string { // pad spaces for each line if msgI == nil { return "" } return fmtMessage(msgI.(string)) - }, - FormatLevel: func(_ any) string { - return levelStr - }, - } - return zerolog.New( - writer, - ).Level(level).With().Timestamp().Logger() + } + }) + return zerolog.New(writer).Level(level).With().Timestamp().Logger() } -func InitLogger(out ...io.Writer) { - logger = NewLogger(out...) - log.SetOutput(logger) - log.SetPrefix("") - log.SetFlags(0) - zerolog.TimeFieldFormat = timeFmt - zerologlog.Logger = logger +func NewLoggerWithFixedLevel(level zerolog.Level, out ...io.Writer) zerolog.Logger { + writer := zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) { + w.Out = multiLevelWriter(out...) + w.TimeFormat = timeFmt + w.FormatMessage = func(msgI any) string { // pad spaces for each line + if msgI == nil { + return "" + } + return fmtMessage(msgI.(string)) + } + }) + return zerolog.New(writer).Level(level).With().Str("level", level.String()).Timestamp().Logger() } diff --git a/internal/route/rules/presets/embed.go b/internal/route/rules/presets/embed.go index f9f83b61..77e4d7ba 100644 --- a/internal/route/rules/presets/embed.go +++ b/internal/route/rules/presets/embed.go @@ -8,6 +8,7 @@ import ( "github.com/rs/zerolog/log" "github.com/yusing/godoxy/internal/route/rules" "github.com/yusing/godoxy/internal/serialization" + gperr "github.com/yusing/goutils/errs" ) //go:embed *.yml @@ -34,12 +35,12 @@ func initPresets() { var rules rules.Rules content, err := fs.ReadFile(file.Name()) if err != nil { - log.Error().Str("name", file.Name()).Err(err).Msg("failed to read rule preset") + gperr.LogError("failed to read rule preset", err) continue } _, err = serialization.ConvertString(string(content), reflect.ValueOf(&rules)) if err != nil { - log.Error().Str("name", file.Name()).Err(err).Msg("failed to unmarshal rule preset") + gperr.LogError("failed to unmarshal rule preset", err) continue } rulePresets[file.Name()] = rules