1 Star 1 Fork 0

titan-kit / titan

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
slf4g.go 5.78 KB
一键复制 编辑 原始数据 按行查看 历史
蝶衣人生 提交于 2021-05-29 14:04 . first commit
package log
import (
"bytes"
"fmt"
"io"
"log"
"runtime"
"strconv"
"strings"
"sync"
"time"
)
var (
// DefaultCaller 是返回文件和行的评估器.
DefaultCaller = Caller(3)
// DefaultLogger 是默认记录器.
DefaultLogger = NewStdLogger("[Titan] ", log.Writer())
// DefaultCallerLogger 是默认返回文件和行的评估器记录器.
DefaultCallerLogger = With(DefaultLogger, "caller", DefaultCaller)
// DefaultTimestamp 是一个返回当前时钟时间的评估器.
DefaultTimestamp = Timestamp(time.RFC3339)
)
// Level 是记录器级别.
type Level int8
// LevelKey 是记录器级别的键.
const LevelKey = "level"
const (
// DEBUG 用于调试日志
DEBUG Level = iota
// INFO 基本日志
INFO
// WARNING 用于警告日志
WARNING
// ERROR 用于错误日志
ERROR
// CRITICAL 用于严重错误日志
CRITICAL
)
func (l Level) String() string {
switch l {
case DEBUG:
return "DEBUG"
case INFO:
return "INFO"
case WARNING:
return "WARNING"
case ERROR:
return "ERROR"
case CRITICAL:
return "CRITICAL"
default:
return ""
}
}
// Logger 是记录器接口.
type Logger interface {
Log(pairs ...interface{}) error
}
type context struct {
logs []Logger
prefix []interface{}
hasValuer bool
}
func (c *context) Log(kv ...interface{}) error {
kvs := make([]interface{}, 0, len(c.prefix)+len(kv))
kvs = append(kvs, c.prefix...)
if c.hasValuer {
bindValues(kvs)
}
kvs = append(kvs, kv...)
for _, l := range c.logs {
if err := l.Log(kvs...); err != nil {
return err
}
}
return nil
}
// With 与记录器字段.
func With(l Logger, kv ...interface{}) Logger {
if c, ok := l.(*context); ok {
kvs := make([]interface{}, 0, len(c.prefix)+len(kv))
kvs = append(kvs, kv...)
kvs = append(kvs, c.prefix...)
return &context{logs: c.logs, prefix: kvs, hasValuer: containsValuer(kvs)}
}
return &context{logs: []Logger{l}, prefix: kv, hasValuer: containsValuer(kv)}
}
// MultiLogger 包装多记录器.
func MultiLogger(logs ...Logger) Logger {
return &context{logs: logs}
}
func Debug(log Logger) Logger {
return With(log, LevelKey, DEBUG)
}
func Info(log Logger) Logger {
return With(log, LevelKey, INFO)
}
func Warning(log Logger) Logger {
return With(log, LevelKey, WARNING)
}
func Error(log Logger) Logger {
return With(log, LevelKey, ERROR)
}
func Critical(log Logger) Logger {
return With(log, LevelKey, CRITICAL)
}
// Slf4g 是记录器助手.
type Slf4g struct {
debug Logger
info Logger
warning Logger
err Logger
critical Logger
}
// NewSlf4g 新的记录器助手.
func NewSlf4g(name string, logger Logger) *Slf4g {
slf4g := With(logger, "module", name)
return &Slf4g{debug: Debug(slf4g), info: Info(slf4g), warning: Warning(slf4g), err: Error(slf4g), critical: Critical(slf4g)}
}
func (h *Slf4g) Debug(a ...interface{}) {
h.debug.Log("msg", fmt.Sprint(a...))
}
func (h *Slf4g) DebugF(format string, a ...interface{}) {
h.debug.Log("msg", fmt.Sprintf(format, a...))
}
func (h *Slf4g) DebugW(pairs ...interface{}) {
h.debug.Log(pairs...)
}
func (h *Slf4g) Info(a ...interface{}) {
h.info.Log("msg", fmt.Sprint(a...))
}
func (h *Slf4g) InfoF(format string, a ...interface{}) {
h.info.Log("msg", fmt.Sprintf(format, a...))
}
func (h *Slf4g) InfoW(pairs ...interface{}) {
h.info.Log(pairs...)
}
func (h *Slf4g) Warning(a ...interface{}) {
h.warning.Log("msg", fmt.Sprint(a...))
}
func (h *Slf4g) WarningF(format string, a ...interface{}) {
h.warning.Log("msg", fmt.Sprintf(format, a...))
}
func (h *Slf4g) WarningW(pairs ...interface{}) {
h.warning.Log(pairs...)
}
func (h *Slf4g) Error(a ...interface{}) {
h.err.Log("msg", fmt.Sprint(a...))
}
func (h *Slf4g) ErrorF(format string, a ...interface{}) {
h.err.Log("msg", fmt.Sprintf(format, a...))
}
func (h *Slf4g) ErrorW(pairs ...interface{}) {
h.err.Log(pairs...)
}
func (h *Slf4g) Critical(a ...interface{}) {
h.critical.Log("msg", fmt.Sprint(a...))
}
func (h *Slf4g) CriticalF(format string, a ...interface{}) {
h.critical.Log("msg", fmt.Sprintf(format, a...))
}
func (h *Slf4g) CriticalW(pairs ...interface{}) {
h.critical.Log(pairs...)
}
// Valuer 是返回一个日志值.
type Valuer func() interface{}
// Value 返回函数值.
func Value(v interface{}) interface{} {
if v, ok := v.(Valuer); ok {
return v()
}
return v
}
// Caller 返回一个Valuer,该Valuer返回一个pkg/file:调用方的行描述.
func Caller(depth int) Valuer {
return func() interface{} {
_, file, line, _ := runtime.Caller(depth)
if strings.LastIndex(file, "gitee.com/titan-kit/titan/log") > 0 {
_, file, line, _ = runtime.Caller(depth + 1)
}
idx := strings.LastIndexByte(file, '/')
return file[idx+1:] + ":" + strconv.Itoa(line)
}
}
var _ Logger = (*stdLogger)(nil)
type stdLogger struct {
log *log.Logger
pool *sync.Pool
}
// NewStdLogger 带有选项的新标准记录器.
func NewStdLogger(prefix string, w io.Writer) Logger {
return &stdLogger{log: log.New(w, prefix, log.LstdFlags), pool: &sync.Pool{New: func() interface{} { return new(bytes.Buffer) }}}
}
// Log 打印KV对日志.
func (l *stdLogger) Log(kv ...interface{}) error {
if len(kv) == 0 {
return nil
}
if len(kv)%2 != 0 {
kv = append(kv, "")
}
buf := l.pool.Get().(*bytes.Buffer)
for i := 0; i < len(kv); i += 2 {
_, _ = fmt.Fprintf(buf, "%s=%v ", kv[i], kv[i+1])
}
_ = l.log.Output(4, buf.String())
buf.Reset()
l.pool.Put(buf)
return nil
}
// Timestamp 返回具有自定义时间格式的时间戳评估器.
func Timestamp(layout string) Valuer {
return func() interface{} {
return time.Now().Format(layout)
}
}
func bindValues(keys []interface{}) {
for i := 1; i < len(keys); i += 2 {
if v, ok := keys[i].(Valuer); ok {
keys[i] = v()
}
}
}
func containsValuer(keys []interface{}) bool {
for i := 1; i < len(keys); i += 2 {
if _, ok := keys[i].(Valuer); ok {
return true
}
}
return false
}
1
https://gitee.com/titan-kit/titan.git
git@gitee.com:titan-kit/titan.git
titan-kit
titan
titan
v0.0.4

搜索帮助