This commit is contained in:
杭州明婳科技
2026-04-30 23:26:14 +08:00
commit 2dfcbbbb22
76 changed files with 17478 additions and 0 deletions
+202
View File
@@ -0,0 +1,202 @@
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...)
}
+28
View File
@@ -0,0 +1,28 @@
package console_test
import (
"testing"
"github.com/EthanCodeCraft/xlgo-core/console"
)
func TestConsole(t *testing.T) {
// 使用默认控制台
console.Debug("这是一条调试信息")
console.Info("这是一条普通信息")
console.Success("这是一条成功信息")
console.Warn("这是一条警告信息")
console.Error("这是一条错误信息")
// 创建自定义控制台
c := console.New(
console.WithColor(true),
console.WithTime(true),
console.WithCaller(true, 2),
)
c.Debug("自定义控制台 - Debug")
c.Info("自定义控制台 - Info")
c.Success("自定义控制台 - Success")
c.Warn("自定义控制台 - Warn")
c.Error("自定义控制台 - Error")
}
+15
View File
@@ -0,0 +1,15 @@
//go:build linux || darwin
package console
import (
"fmt"
)
// printColor 彩色打印(使用ANSI转义序列)
func (c *Console) printColor(code, msg string) {
// \033[ 是ANSI转义序列起始
// %sm 是颜色代码
// \033[0m 是重置颜色
fmt.Fprintf(c.output, "\033[%sm%s\033[0m\n", code, msg)
}
+51
View File
@@ -0,0 +1,51 @@
//go:build windows
package console
import (
"fmt"
"syscall"
"unsafe"
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
// 颜色映射:ANSI -> Windows控制台颜色
// 0 黑色, 1 蓝色, 2 绿色, 3 青色, 4 红色, 5 紫色, 6 黄色, 7 淡灰色
// 8 灰色, 9 亮蓝色, 10 亮绿色, 11 亮青色, 12 亮红色, 13 亮紫色, 14 亮黄色, 15 白色
var colorMap = map[string]uintptr{
"0;36": 11, // 青色 -> 亮青色
"0;37": 15, // 白色 -> 白色
"0;92": 10, // 亮绿色
"1;93": 14, // 亮黄色
"1;31": 12, // 亮红色
}
// printColor 彩色打印
func (c *Console) printColor(code, msg string) {
color := colorMap[code]
if color == 0 {
color = 7 // 默认淡灰色
}
proc := kernel32.NewProc("SetConsoleTextAttribute")
_, _, _ = proc.Call(uintptr(syscall.Stdout), color)
fmt.Fprintln(c.output, msg)
_, _, _ = proc.Call(uintptr(syscall.Stdout), 7) // 恢复默认颜色
}
// EnableVirtualTerminal 启用虚拟终端支持(Windows 10+)
func EnableVirtualTerminal() error {
// 尝试启用 ANSI 转义序列支持
proc := kernel32.NewProc("GetConsoleMode")
var mode uint32
_, _, err := proc.Call(uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&mode)))
if err != syscall.Errno(0) {
return err
}
mode |= 0x0004 // ENABLE_VIRTUAL_TERMINAL_PROCESSING
proc = kernel32.NewProc("SetConsoleMode")
_, _, err = proc.Call(uintptr(syscall.Stdout), uintptr(mode))
return err
}