Files
ngzz-mc/internal/logx/log.go

82 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package logx 分级日志debug/info/warn/error输出 stderr 与可选文件。
package logx
import (
"fmt"
"io"
"os"
"sync"
"time"
)
// Level 日志级别。
type Level int
const (
// LevelDebug 调试。
LevelDebug Level = iota
// LevelInfo 常规信息。
LevelInfo
// LevelWarn 警告。
LevelWarn
// LevelError 错误。
LevelError
)
// Logger 线程安全分级日志器。
type Logger struct {
mu sync.Mutex
level Level
w io.Writer
}
// New 创建日志器file 为空仅输出 stderr。
func New(file string, level Level) (*Logger, error) {
w := io.Writer(os.Stderr)
if file != "" {
if err := os.MkdirAll(pathDir(file), 0o755); err != nil {
return nil, fmt.Errorf("logx.New mkdir: %w", err)
}
f, err := os.OpenFile(file, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
if err != nil {
return nil, fmt.Errorf("logx.New %s: %w", file, err)
}
w = io.MultiWriter(os.Stderr, f)
}
return &Logger{level: level, w: w}, nil
}
// pathDir 返回路径的目录部分("a.log" → ".")。
func pathDir(p string) string {
for i := len(p) - 1; i >= 0; i-- {
if p[i] == '/' || p[i] == '\\' {
if i == 0 {
return p[:1]
}
return p[:i]
}
}
return "."
}
func (l *Logger) logf(lv Level, tag, format string, args ...any) {
if lv < l.level {
return
}
l.mu.Lock()
defer l.mu.Unlock()
fmt.Fprintf(l.w, "[%s] [%s] %s\n", time.Now().Format("15:04:05.000"), tag, fmt.Sprintf(format, args...))
}
// Debugf 调试输出。
func (l *Logger) Debugf(format string, args ...any) { l.logf(LevelDebug, "DEBUG", format, args...) }
// Infof 常规输出。
func (l *Logger) Infof(format string, args ...any) { l.logf(LevelInfo, "INFO", format, args...) }
// Warnf 警告输出。
func (l *Logger) Warnf(format string, args ...any) { l.logf(LevelWarn, "WARN", format, args...) }
// Errorf 错误输出。
func (l *Logger) Errorf(format string, args ...any) { l.logf(LevelError, "ERROR", format, args...) }