init
This commit is contained in:
@@ -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...)
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user