| @@ -0,0 +1,112 @@ | |||||
| package logger | |||||
| import ( | |||||
| "fmt" | |||||
| "os" | |||||
| "path/filepath" | |||||
| "strings" | |||||
| nested "github.com/antonfisher/nested-logrus-formatter" | |||||
| "github.com/sirupsen/logrus" | |||||
| myreflect "gitlink.org.cn/cloudream/common/utils/reflect" | |||||
| ) | |||||
| // Init 初始化全局默认的日志器 | |||||
| func Init(cfg *Config) error { | |||||
| logrus.SetFormatter(&nested.Formatter{ | |||||
| TimestampFormat: "2006-01-02 15:04:05", | |||||
| NoColors: true, | |||||
| NoFieldsColors: true, | |||||
| }) | |||||
| level, ok := loggerLevels[strings.ToUpper(cfg.Level)] | |||||
| if !ok { | |||||
| return fmt.Errorf("invalid log level: %s", cfg.Level) | |||||
| } | |||||
| logrus.SetLevel(level) | |||||
| output := strings.ToUpper(cfg.Output) | |||||
| if output == OUTPUT_FILE { | |||||
| logFilePath := filepath.Join(cfg.OutputDirectory, cfg.OutputFileName+".log") | |||||
| if err := os.MkdirAll(cfg.OutputDirectory, 0644); err != nil { | |||||
| return err | |||||
| } | |||||
| file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE, 0644) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| logrus.SetOutput(file) | |||||
| } else if output == OUTPUT_STDOUT { | |||||
| logrus.SetOutput(os.Stdout) | |||||
| } else { | |||||
| logrus.SetOutput(os.Stdout) | |||||
| logrus.Warnf("unsupported output: %s, will output to stdout", output) | |||||
| } | |||||
| return nil | |||||
| } | |||||
| func Debug(args ...interface{}) { | |||||
| logrus.Debug(args...) | |||||
| } | |||||
| func Debugf(format string, args ...interface{}) { | |||||
| logrus.Debugf(format, args...) | |||||
| } | |||||
| func Info(args ...interface{}) { | |||||
| logrus.Info(args...) | |||||
| } | |||||
| func Infof(format string, args ...interface{}) { | |||||
| logrus.Infof(format, args...) | |||||
| } | |||||
| func Warn(args ...interface{}) { | |||||
| logrus.Warn(args...) | |||||
| } | |||||
| func Warnf(format string, args ...interface{}) { | |||||
| logrus.Warnf(format, args...) | |||||
| } | |||||
| func Error(args ...interface{}) { | |||||
| logrus.Error(args...) | |||||
| } | |||||
| func Errorf(format string, args ...interface{}) { | |||||
| logrus.Errorf(format, args...) | |||||
| } | |||||
| func Fatal(args ...interface{}) { | |||||
| logrus.Fatal(args...) | |||||
| } | |||||
| func Fatalf(format string, args ...interface{}) { | |||||
| logrus.Fatalf(format, args...) | |||||
| } | |||||
| func Panic(args ...interface{}) { | |||||
| logrus.Panic(args...) | |||||
| } | |||||
| func Panicf(format string, args ...interface{}) { | |||||
| logrus.Panicf(format, args...) | |||||
| } | |||||
| func WithField(key string, val any) Logger { | |||||
| return &logrusLogger{ | |||||
| entry: logrus.WithField(key, val), | |||||
| } | |||||
| } | |||||
| func WithType[T any](key string) Logger { | |||||
| return &logrusLogger{ | |||||
| entry: logrus.WithField(key, myreflect.TypeOf[T]().Name()), | |||||
| } | |||||
| } | |||||
| @@ -1,12 +1,8 @@ | |||||
| package logger | package logger | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "os" | |||||
| "path/filepath" | |||||
| "strings" | |||||
| "reflect" | |||||
| nested "github.com/antonfisher/nested-logrus-formatter" | |||||
| "github.com/sirupsen/logrus" | "github.com/sirupsen/logrus" | ||||
| ) | ) | ||||
| @@ -33,94 +29,26 @@ var loggerLevels = map[string]logrus.Level{ | |||||
| PANIC_LEVEL: logrus.PanicLevel, | PANIC_LEVEL: logrus.PanicLevel, | ||||
| } | } | ||||
| // Init 初始化全局默认的日志器 | |||||
| func Init(cfg *Config) error { | |||||
| logrus.SetFormatter(&nested.Formatter{ | |||||
| TimestampFormat: "2006-01-02 15:04:05", | |||||
| NoColors: true, | |||||
| NoFieldsColors: true, | |||||
| }) | |||||
| type Logger interface { | |||||
| Debug(args ...interface{}) | |||||
| Debugf(format string, args ...interface{}) | |||||
| level, ok := loggerLevels[strings.ToUpper(cfg.Level)] | |||||
| if !ok { | |||||
| return fmt.Errorf("invalid log level: %s", cfg.Level) | |||||
| } | |||||
| Info(args ...interface{}) | |||||
| Infof(format string, args ...interface{}) | |||||
| logrus.SetLevel(level) | |||||
| Warn(args ...interface{}) | |||||
| Warnf(format string, args ...interface{}) | |||||
| output := strings.ToUpper(cfg.Output) | |||||
| Error(args ...interface{}) | |||||
| Errorf(format string, args ...interface{}) | |||||
| if output == OUTPUT_FILE { | |||||
| logFilePath := filepath.Join(cfg.OutputDirectory, cfg.OutputFileName+".log") | |||||
| Fatal(args ...interface{}) | |||||
| Fatalf(format string, args ...interface{}) | |||||
| if err := os.MkdirAll(cfg.OutputDirectory, 0644); err != nil { | |||||
| return err | |||||
| } | |||||
| Panic(args ...interface{}) | |||||
| Panicf(format string, args ...interface{}) | |||||
| file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE, 0644) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| logrus.SetOutput(file) | |||||
| WithField(key string, val any) Logger | |||||
| } else if output == OUTPUT_STDOUT { | |||||
| logrus.SetOutput(os.Stdout) | |||||
| } else { | |||||
| logrus.SetOutput(os.Stdout) | |||||
| logrus.Warnf("unsupported output: %s, will output to stdout", output) | |||||
| } | |||||
| return nil | |||||
| } | |||||
| func Debug(args ...interface{}) { | |||||
| logrus.Debug(args...) | |||||
| } | |||||
| func Debugf(format string, args ...interface{}) { | |||||
| logrus.Debugf(format, args...) | |||||
| } | |||||
| func Info(args ...interface{}) { | |||||
| logrus.Info(args...) | |||||
| } | |||||
| func Infof(format string, args ...interface{}) { | |||||
| logrus.Infof(format, args...) | |||||
| } | |||||
| func Warn(args ...interface{}) { | |||||
| logrus.Warn(args...) | |||||
| } | |||||
| func Warnf(format string, args ...interface{}) { | |||||
| logrus.Warnf(format, args...) | |||||
| } | |||||
| func Error(args ...interface{}) { | |||||
| logrus.Error(args...) | |||||
| } | |||||
| func Errorf(format string, args ...interface{}) { | |||||
| logrus.Errorf(format, args...) | |||||
| } | |||||
| func Fatal(args ...interface{}) { | |||||
| logrus.Fatal(args...) | |||||
| } | |||||
| func Fatalf(format string, args ...interface{}) { | |||||
| logrus.Fatalf(format, args...) | |||||
| } | |||||
| func Panic(args ...interface{}) { | |||||
| logrus.Panic(args...) | |||||
| } | |||||
| func Panicf(format string, args ...interface{}) { | |||||
| logrus.Panicf(format, args...) | |||||
| } | |||||
| func WithField(key string, val any) *logrus.Entry { | |||||
| return logrus.WithField(key, val) | |||||
| WithType(key string, typ reflect.Type) Logger | |||||
| } | } | ||||
| @@ -0,0 +1,65 @@ | |||||
| package logger | |||||
| import ( | |||||
| "reflect" | |||||
| "github.com/sirupsen/logrus" | |||||
| ) | |||||
| type logrusLogger struct { | |||||
| entry *logrus.Entry | |||||
| } | |||||
| func (l *logrusLogger) Debug(args ...interface{}) { | |||||
| l.entry.Debug(args...) | |||||
| } | |||||
| func (l *logrusLogger) Debugf(format string, args ...interface{}) { | |||||
| l.entry.Debugf(format, args...) | |||||
| } | |||||
| func (l *logrusLogger) Info(args ...interface{}) { | |||||
| l.entry.Info(args...) | |||||
| } | |||||
| func (l *logrusLogger) Infof(format string, args ...interface{}) { | |||||
| l.entry.Infof(format, args...) | |||||
| } | |||||
| func (l *logrusLogger) Warn(args ...interface{}) { | |||||
| l.entry.Warn(args...) | |||||
| } | |||||
| func (l *logrusLogger) Warnf(format string, args ...interface{}) { | |||||
| l.entry.Warnf(format, args...) | |||||
| } | |||||
| func (l *logrusLogger) Error(args ...interface{}) { | |||||
| l.entry.Error(args...) | |||||
| } | |||||
| func (l *logrusLogger) Errorf(format string, args ...interface{}) { | |||||
| l.entry.Errorf(format, args...) | |||||
| } | |||||
| func (l *logrusLogger) Fatal(args ...interface{}) { | |||||
| l.entry.Fatal(args...) | |||||
| } | |||||
| func (l *logrusLogger) Fatalf(format string, args ...interface{}) { | |||||
| l.entry.Fatalf(format, args...) | |||||
| } | |||||
| func (l *logrusLogger) Panic(args ...interface{}) { | |||||
| l.entry.Panic(args...) | |||||
| } | |||||
| func (l *logrusLogger) Panicf(format string, args ...interface{}) { | |||||
| l.entry.Panicf(format, args...) | |||||
| } | |||||
| func (l *logrusLogger) WithField(key string, val any) Logger { | |||||
| return &logrusLogger{ | |||||
| entry: l.entry.WithField(key, val), | |||||
| } | |||||
| } | |||||
| func (l *logrusLogger) WithType(key string, typ reflect.Type) Logger { | |||||
| return &logrusLogger{ | |||||
| entry: l.entry.WithField(key, typ.Name()), | |||||
| } | |||||
| } | |||||
| @@ -1,30 +1,28 @@ | |||||
| package typedispatcher | package typedispatcher | ||||
| import ( | import ( | ||||
| "reflect" | |||||
| myreflect "gitlink.org.cn/cloudream/common/utils/reflect" | myreflect "gitlink.org.cn/cloudream/common/utils/reflect" | ||||
| ) | ) | ||||
| type HandlerFn[TRet any] func(val any) TRet | type HandlerFn[TRet any] func(val any) TRet | ||||
| type TypeDispatcher[TRet any] struct { | type TypeDispatcher[TRet any] struct { | ||||
| handlers map[reflect.Type]HandlerFn[TRet] | |||||
| handlers map[myreflect.Type]HandlerFn[TRet] | |||||
| } | } | ||||
| func NewTypeDispatcher[TRet any]() TypeDispatcher[TRet] { | func NewTypeDispatcher[TRet any]() TypeDispatcher[TRet] { | ||||
| return TypeDispatcher[TRet]{ | return TypeDispatcher[TRet]{ | ||||
| handlers: make(map[reflect.Type]HandlerFn[TRet]), | |||||
| handlers: make(map[myreflect.Type]HandlerFn[TRet]), | |||||
| } | } | ||||
| } | } | ||||
| func (t *TypeDispatcher[TRet]) Add(typ reflect.Type, fn HandlerFn[TRet]) { | |||||
| func (t *TypeDispatcher[TRet]) Add(typ myreflect.Type, fn HandlerFn[TRet]) { | |||||
| t.handlers[typ] = fn | t.handlers[typ] = fn | ||||
| } | } | ||||
| func (t *TypeDispatcher[TRet]) Dispatch(val any) (TRet, bool) { | func (t *TypeDispatcher[TRet]) Dispatch(val any) (TRet, bool) { | ||||
| var ret TRet | var ret TRet | ||||
| typ := reflect.TypeOf(val) | |||||
| typ := myreflect.TypeOfValue(val) | |||||
| handler, ok := t.handlers[typ] | handler, ok := t.handlers[typ] | ||||
| if !ok { | if !ok { | ||||
| return ret, false | return ret, false | ||||
| @@ -34,7 +32,7 @@ func (t *TypeDispatcher[TRet]) Dispatch(val any) (TRet, bool) { | |||||
| } | } | ||||
| func Add[T any, TRet any](dispatcher TypeDispatcher[TRet], handler func(val T) TRet) { | func Add[T any, TRet any](dispatcher TypeDispatcher[TRet], handler func(val T) TRet) { | ||||
| dispatcher.Add(myreflect.GetGenericType[T](), func(val any) TRet { | |||||
| dispatcher.Add(myreflect.TypeOf[T](), func(val any) TRet { | |||||
| return handler(val.(T)) | return handler(val.(T)) | ||||
| }) | }) | ||||
| } | } | ||||
| @@ -2,12 +2,19 @@ package reflect | |||||
| import "reflect" | import "reflect" | ||||
| // GetGenericType 获得泛型的类型 | |||||
| func GetGenericType[T any]() reflect.Type { | |||||
| type Type = reflect.Type | |||||
| // TypeOfValue 获得实际值的类型 | |||||
| func TypeOfValue(val any) reflect.Type { | |||||
| return reflect.TypeOf(val) | |||||
| } | |||||
| // TypeOf 获得泛型的类型 | |||||
| func TypeOf[T any]() reflect.Type { | |||||
| return reflect.TypeOf([0]T{}).Elem() | return reflect.TypeOf([0]T{}).Elem() | ||||
| } | } | ||||
| // GetGenericElemType 获得泛型的类型。适用于数组、指针类型 | |||||
| func GetGenericElemType[T any]() reflect.Type { | |||||
| // ElemTypeOf 获得泛型的类型。适用于数组、指针类型 | |||||
| func ElemTypeOf[T any]() reflect.Type { | |||||
| return reflect.TypeOf([0]T{}).Elem().Elem() | return reflect.TypeOf([0]T{}).Elem().Elem() | ||||
| } | } | ||||
| @@ -67,7 +67,7 @@ func Test_TypedMapToObject(t *testing.T) { | |||||
| } | } | ||||
| nameResovler := NewTypeNameResolver(true) | nameResovler := NewTypeNameResolver(true) | ||||
| nameResovler.Register(myreflect.GetGenericType[Struct]()) | |||||
| nameResovler.Register(myreflect.TypeOf[Struct]()) | |||||
| Convey("结构体", t, func() { | Convey("结构体", t, func() { | ||||
| st := Struct{ | st := Struct{ | ||||