golang-study/simplelog/simplelog.go

156 lines
2.8 KiB
Go

package simplelog
import (
"fmt"
"io"
"os"
"runtime"
"time"
)
// 自定义日志
type LogLevel struct {
s string
flag LevelFlag
}
func (l LogLevel) String() string {
return l.s
}
type LevelFlag int
const (
FlagInfo LevelFlag = 0x1
FlagWarn LevelFlag = 0x2
FlagError LevelFlag = 0x4
FlagDebug LevelFlag = 0x8
)
var (
INFO = LogLevel{"INFO", FlagInfo}
WARN = LogLevel{"WARN", FlagWarn}
ERROR = LogLevel{"ERROR", FlagError}
DEBUG = LogLevel{"DEBUG", FlagDebug}
)
// Logger 日志类
type Logger struct {
w io.Writer
timeFormat string
loggerFormat string
flag LevelFlag
}
func (l *Logger) time() string {
now := time.Now()
return now.Format(l.timeFormat)
}
func (l *Logger) PrintLog(level LogLevel, log string) {
// 根据 flag 位 限制日志级别
if l.flag&level.flag != level.flag {
return
}
pc, _, _, ok := runtime.Caller(2)
var f *runtime.Func
if ok {
f = runtime.FuncForPC(pc)
_, _ = fmt.Fprintf(l.w, l.loggerFormat, l.time(), level, pc, f.Name(), log)
} else {
_, _ = fmt.Fprintf(l.w, l.loggerFormat, l.time(), level, "--", "Unknown", log)
}
}
// Debug 调试输出
func (l *Logger) Debug(log string) {
l.PrintLog(DEBUG, log)
}
// Info 消息输出
func (l *Logger) Info(log string) {
l.PrintLog(INFO, log)
}
// Warn 消息输出
func (l *Logger) Warn(log string) {
l.PrintLog(WARN, log)
}
// Error 消息输出
func (l *Logger) Error(log string) {
pc, file, line, ok := runtime.Caller(1)
l.PrintLog(ERROR, log)
if ok {
_, _ = fmt.Fprintf(l.w, "=> %d %s\tline: %d\n", pc, file, line)
} else {
_, _ = fmt.Fprintf(l.w, "=> Unknown Unknown : Unknown\n")
}
}
// 函数式 选项模式
type Option struct {
Writer io.Writer
TimeFormat string
LogFormat string
LevelFlag LevelFlag
}
type OptionFunc func(*Option)
func WithWriter(writer io.Writer) OptionFunc {
return func(option *Option) {
option.Writer = writer
}
}
func WithTimeFormat(timeFormat string) OptionFunc {
return func(option *Option) {
option.TimeFormat = timeFormat
}
}
func WithLogFormat(logFormat string) OptionFunc {
return func(option *Option) {
option.LogFormat = logFormat
}
}
func WithLogFlag(flag LevelFlag) OptionFunc {
return func(option *Option) {
option.LevelFlag = flag
}
}
// 默认参数
var defaultOption = &Option{
Writer: os.Stdout,
TimeFormat: "2006-01-02 15:04:05.99",
LogFormat: "%-22s %s %v --- [%20s] : %s\n",
LevelFlag: FlagInfo | FlagWarn | FlagError | FlagDebug,
}
// NewOption 构造 Option 参数
func NewOption(opts ...OptionFunc) (opt *Option) {
opt = defaultOption
for _, o := range opts {
o(opt)
}
return
}
// NewLog 构造函数
func NewLog(opts ...OptionFunc) *Logger {
opt := NewOption(opts...)
return &Logger{
w: opt.Writer,
timeFormat: opt.TimeFormat,
loggerFormat: opt.LogFormat,
flag: opt.LevelFlag,
}
}