Files
xlgo-core/console/console.go
T
杭州明婳科技 2dfcbbbb22 init
2026-04-30 23:26:14 +08:00

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...)
}