203 lines
3.7 KiB
Go
203 lines
3.7 KiB
Go
package console
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Level 日志级别
|
|
type Level int
|
|
|
|
const (
|
|
LevelDebug Level = iota
|
|
LevelInfo
|
|
LevelSuccess
|
|
LevelWarn
|
|
LevelError
|
|
)
|
|
|
|
// Color 颜色定义
|
|
type Color struct {
|
|
Code string
|
|
Name string
|
|
}
|
|
|
|
var colors = map[Level]Color{
|
|
LevelDebug: {Code: "0;36", Name: "Debug"}, // 青色
|
|
LevelInfo: {Code: "0;37", Name: "Info"}, // 白色
|
|
LevelSuccess: {Code: "0;92", Name: "Success"}, // 亮绿色
|
|
LevelWarn: {Code: "1;93", Name: "Warn"}, // 亮黄色
|
|
LevelError: {Code: "1;31", Name: "Error"}, // 亮红色
|
|
}
|
|
|
|
// Console 控制台打印器
|
|
type Console struct {
|
|
output io.Writer
|
|
isColor bool
|
|
showTime bool
|
|
showCall bool
|
|
timeFmt string
|
|
skipCall int
|
|
}
|
|
|
|
// Option 配置选项
|
|
type Option func(*Console)
|
|
|
|
// WithOutput 设置输出目标
|
|
func WithOutput(w io.Writer) Option {
|
|
return func(c *Console) {
|
|
c.output = w
|
|
}
|
|
}
|
|
|
|
// WithColor 设置是否启用颜色
|
|
func WithColor(enable bool) Option {
|
|
return func(c *Console) {
|
|
c.isColor = enable
|
|
}
|
|
}
|
|
|
|
// WithTime 设置是否显示时间
|
|
func WithTime(show bool) Option {
|
|
return func(c *Console) {
|
|
c.showTime = show
|
|
}
|
|
}
|
|
|
|
// WithCaller 设置是否显示调用位置
|
|
func WithCaller(show bool, skip int) Option {
|
|
return func(c *Console) {
|
|
c.showCall = show
|
|
c.skipCall = skip
|
|
}
|
|
}
|
|
|
|
// WithTimeFormat 设置时间格式
|
|
func WithTimeFormat(fmt string) Option {
|
|
return func(c *Console) {
|
|
c.timeFmt = fmt
|
|
}
|
|
}
|
|
|
|
// New 创建控制台打印器
|
|
func New(opts ...Option) *Console {
|
|
c := &Console{
|
|
output: os.Stdout,
|
|
isColor: true,
|
|
showTime: true,
|
|
showCall: true,
|
|
timeFmt: "15:04:05.000",
|
|
skipCall: 2,
|
|
}
|
|
for _, opt := range opts {
|
|
opt(c)
|
|
}
|
|
return c
|
|
}
|
|
|
|
// Default 默认控制台
|
|
var Default = New()
|
|
|
|
// print 内部打印函数
|
|
func (c *Console) print(level Level, s ...any) {
|
|
var sb strings.Builder
|
|
|
|
// 时间
|
|
if c.showTime {
|
|
sb.WriteString(time.Now().Format(c.timeFmt))
|
|
sb.WriteString(" ")
|
|
}
|
|
|
|
// 级别名称
|
|
color := colors[level]
|
|
sb.WriteString("[")
|
|
sb.WriteString(color.Name)
|
|
sb.WriteString("] ")
|
|
|
|
// 调用位置
|
|
if c.showCall {
|
|
sb.WriteString(c.getCaller())
|
|
sb.WriteString(" ")
|
|
}
|
|
|
|
// 内容
|
|
sb.WriteString(fmt.Sprint(s...))
|
|
|
|
// 输出
|
|
if c.isColor {
|
|
c.printColor(color.Code, sb.String())
|
|
} else {
|
|
fmt.Fprintln(c.output, sb.String())
|
|
}
|
|
}
|
|
|
|
// getCaller 获取调用位置
|
|
func (c *Console) getCaller() string {
|
|
_, file, line, ok := runtime.Caller(c.skipCall)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
// 只取文件名
|
|
idx := strings.LastIndex(file, "/")
|
|
if idx >= 0 {
|
|
file = file[idx+1:]
|
|
}
|
|
return fmt.Sprintf("%s:%d", file, line)
|
|
}
|
|
|
|
// Debug 打印调试信息(青色)
|
|
func (c *Console) Debug(s ...any) {
|
|
c.print(LevelDebug, s...)
|
|
}
|
|
|
|
// Info 打印普通信息(白色)
|
|
func (c *Console) Info(s ...any) {
|
|
c.print(LevelInfo, s...)
|
|
}
|
|
|
|
// Success 打印成功信息(绿色)
|
|
func (c *Console) Success(s ...any) {
|
|
c.print(LevelSuccess, s...)
|
|
}
|
|
|
|
// Warn 打印警告信息(黄色)
|
|
func (c *Console) Warn(s ...any) {
|
|
c.print(LevelWarn, s...)
|
|
}
|
|
|
|
// Error 打印错误信息(红色)
|
|
func (c *Console) Error(s ...any) {
|
|
c.print(LevelError, s...)
|
|
}
|
|
|
|
// ===== 包级别便捷函数 =====
|
|
|
|
// Debug 使用默认控制台打印调试信息
|
|
func Debug(s ...any) {
|
|
Default.print(LevelDebug, s...)
|
|
}
|
|
|
|
// Info 使用默认控制台打印普通信息
|
|
func Info(s ...any) {
|
|
Default.print(LevelInfo, s...)
|
|
}
|
|
|
|
// Success 使用默认控制台打印成功信息
|
|
func Success(s ...any) {
|
|
Default.print(LevelSuccess, s...)
|
|
}
|
|
|
|
// Warn 使用默认控制台打印警告信息
|
|
func Warn(s ...any) {
|
|
Default.print(LevelWarn, s...)
|
|
}
|
|
|
|
// Error 使用默认控制台打印错误信息
|
|
func Error(s ...any) {
|
|
Default.print(LevelError, s...)
|
|
}
|