From f6b990629bf2491f7e43401add07e98875122ce4 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Sat, 7 Oct 2023 17:58:55 +0800 Subject: [PATCH 1/8] :sparkles: feat: support gcs, test enabled --- pkg/config/storage.go | 84 ++++++++++++++++++++++++++++++++++++-- pkg/config/storage_test.go | 18 ++++++-- 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/pkg/config/storage.go b/pkg/config/storage.go index 8129c4d..f7ca2e9 100644 --- a/pkg/config/storage.go +++ b/pkg/config/storage.go @@ -13,8 +13,11 @@ import ( "log" "github.com/aws/aws-sdk-go-v2/aws" + v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" ) // ProviderType storage provider type @@ -63,6 +66,16 @@ var endpointResolverFunc = func(urlTemplate, signingMethod string) s3.EndpointRe } } +var endpointResolverFuncGCS = func(urlTemplate, signingMethod string) s3.EndpointResolverFunc { + return func(region string, options s3.EndpointResolverOptions) (aws.Endpoint, error) { + return aws.Endpoint{ + URL: urlTemplate, + SigningRegion: region, + SigningMethod: signingMethod, + }, nil + } +} + // Storage storage type Storage struct { Type ProviderType `yaml:"type"` @@ -77,11 +90,17 @@ type Storage struct { // Init init func (o *Storage) Init() { var endpointResolver s3.EndpointResolver - if o.Type != S3 { + switch o.Type { + case GCS: + endpointResolver = s3.EndpointResolverFromURL(URLTemplate[GCS]) + o.Region = "auto" + case S3: + default: if urlTemplate, exist := URLTemplate[o.Type]; exist && urlTemplate != "" { endpointResolver = endpointResolverFunc(urlTemplate, o.SigningMethod) } } + if o.Region == "" || o.AccessKeyID == "" || o.SecretAccessKey == "" { //use default config cfg, err := config.LoadDefaultConfig(context.TODO()) @@ -101,8 +120,23 @@ func (o *Storage) Init() { }, nil }), EndpointResolver: endpointResolver, - }, func(o *s3.Options) { - o.EndpointOptions.DisableHTTPS = true + }, func(s3Options *s3.Options) { + switch o.Type { + case GCS: + s3Options.APIOptions = append(s3Options.APIOptions, func(stack *middleware.Stack) error { + if err := stack.Finalize.Insert(dropAcceptEncodingHeader, "Signing", middleware.Before); err != nil { + return err + } + + if err := stack.Finalize.Insert(replaceAcceptEncodingHeader, "Signing", middleware.After); err != nil { + return err + } + + return nil + }) + default: + s3Options.EndpointOptions.DisableHTTPS = true + } }) } @@ -110,3 +144,47 @@ func (o *Storage) Init() { func (o *Storage) GetClient() *s3.Client { return o.client } + +const acceptEncodingHeader = "Accept-Encoding" + +type acceptEncodingKey struct{} + +func GetAcceptEncodingKey(ctx context.Context) (v string) { + v, _ = middleware.GetStackValue(ctx, acceptEncodingKey{}).(string) + return v +} + +func SetAcceptEncodingKey(ctx context.Context, value string) context.Context { + return middleware.WithStackValue(ctx, acceptEncodingKey{}, value) +} + +var dropAcceptEncodingHeader = middleware.FinalizeMiddlewareFunc("DropAcceptEncodingHeader", + func(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (out middleware.FinalizeOutput, metadata middleware.Metadata, err error) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &v4.SigningError{Err: fmt.Errorf("unexpected request middleware type %T", in.Request)} + } + + ae := req.Header.Get(acceptEncodingHeader) + ctx = SetAcceptEncodingKey(ctx, ae) + req.Header.Del(acceptEncodingHeader) + in.Request = req + + return next.HandleFinalize(ctx, in) + }, +) + +var replaceAcceptEncodingHeader = middleware.FinalizeMiddlewareFunc("ReplaceAcceptEncodingHeader", + func(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (out middleware.FinalizeOutput, metadata middleware.Metadata, err error) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &v4.SigningError{Err: fmt.Errorf("unexpected request middleware type %T", in.Request)} + } + + ae := GetAcceptEncodingKey(ctx) + req.Header.Set(acceptEncodingHeader, ae) + in.Request = req + + return next.HandleFinalize(ctx, in) + }, +) diff --git a/pkg/config/storage_test.go b/pkg/config/storage_test.go index 0ea4f32..f8210db 100644 --- a/pkg/config/storage_test.go +++ b/pkg/config/storage_test.go @@ -10,6 +10,7 @@ package config import ( "bytes" "context" + "fmt" "os" "testing" @@ -53,13 +54,24 @@ func TestStorage_Init(t *testing.T) { SecretAccessKey: tt.fields.SecretAccessKey, } o.Init() - _, err := o.GetClient().PutObject(context.TODO(), &s3.PutObjectInput{ - Bucket: aws.String("mss-boot-io"), + res, err := o.GetClient().ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{ + Bucket: aws.String(tt.fields.Bucket), + MaxKeys: 10, + }) + if err != nil { + t.Fatalf("failed to list items: %v", err) + } + + for _, o := range res.Contents { + fmt.Println(">>> ", *o.Key) + } + _, err = o.GetClient().PutObject(context.TODO(), &s3.PutObjectInput{ + Bucket: aws.String(tt.fields.Bucket), Key: aws.String("test.json"), Body: bytes.NewBuffer([]byte(`{"name": "lwx"}`)), }) if err != nil { - t.Errorf("failed to put object: %v", err) + t.Fatalf("failed to put object: %v", err) } }) } From 3c69ecb851384a100ef0d2792e4ad8c5fa9b2ccf Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Sun, 8 Oct 2023 09:15:35 +0800 Subject: [PATCH 2/8] :sparkles: feat: add test --- pkg/config/storage.go | 4 +--- pkg/config/storage_test.go | 45 +++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/pkg/config/storage.go b/pkg/config/storage.go index f7ca2e9..33b6f5c 100644 --- a/pkg/config/storage.go +++ b/pkg/config/storage.go @@ -38,7 +38,7 @@ const ( OBS ProviderType = "obs" // BOS baidu bos BOS ProviderType = "bos" - // GCS google gcs fixme:not tested + // GCS google gcs GCS ProviderType = "gcs" // KS3 kingsoft ks3 KS3 ProviderType = "ks3" @@ -134,8 +134,6 @@ func (o *Storage) Init() { return nil }) - default: - s3Options.EndpointOptions.DisableHTTPS = true } }) } diff --git a/pkg/config/storage_test.go b/pkg/config/storage_test.go index f8210db..a25eab0 100644 --- a/pkg/config/storage_test.go +++ b/pkg/config/storage_test.go @@ -32,14 +32,47 @@ func TestStorage_Init(t *testing.T) { fields fields }{ { - name: "test", + name: "test-oss", fields: fields{ - Type: ProviderType(os.Getenv("s3_provider")), + Type: OSS, SigningMethod: "v4", - Region: os.Getenv("s3_region"), - Bucket: os.Getenv("s3_bucket"), - AccessKeyID: os.Getenv("s3_access_key_id"), - SecretAccessKey: os.Getenv("s3_secret_access_key"), + Region: os.Getenv("oss_region"), + Bucket: os.Getenv("oss_bucket"), + AccessKeyID: os.Getenv("oss_access_key_id"), + SecretAccessKey: os.Getenv("oss_secret_access_key"), + }, + }, + { + name: "test-bos", + fields: fields{ + Type: BOS, + SigningMethod: "v4", + Region: os.Getenv("bos_region"), + Bucket: os.Getenv("bos_bucket"), + AccessKeyID: os.Getenv("bos_access_key_id"), + SecretAccessKey: os.Getenv("bos_secret_access_key"), + }, + }, + { + name: "test-ks3", + fields: fields{ + Type: KS3, + SigningMethod: "v4", + Region: os.Getenv("ks3_region"), + Bucket: os.Getenv("ks3_bucket"), + AccessKeyID: os.Getenv("ks3_access_key_id"), + SecretAccessKey: os.Getenv("ks3_secret_access_key"), + }, + }, + { + name: "test-kodo", + fields: fields{ + Type: KODO, + SigningMethod: "v4", + Region: os.Getenv("kodo_region"), + Bucket: os.Getenv("kodo_bucket"), + AccessKeyID: os.Getenv("kodo_access_key_id"), + SecretAccessKey: os.Getenv("kodo_secret_access_key"), }, }, } From e6328d2cd73f3a30ee87bb02fff0d55147d5de44 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Sat, 21 Oct 2023 21:28:32 +0800 Subject: [PATCH 3/8] :sparkles: feat: support antd pro ui --- pkg/response/model.go | 4 ++-- virtual/model/model_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/response/model.go b/pkg/response/model.go index 8605657..8407464 100644 --- a/pkg/response/model.go +++ b/pkg/response/model.go @@ -18,7 +18,7 @@ type Response struct { type response struct { Response - List interface{} `json:"list,omitempty"` + Data interface{} `json:"data,omitempty"` } // Page page @@ -35,7 +35,7 @@ type page struct { // SetList set data func (e *response) SetList(data interface{}) { - e.List = data + e.Data = data } // Clone clone diff --git a/virtual/model/model_test.go b/virtual/model/model_test.go index 7647f00..25f2802 100644 --- a/virtual/model/model_test.go +++ b/virtual/model/model_test.go @@ -353,7 +353,7 @@ func TestModel_List(t *testing.T) { t.Errorf("Expected status code %d, but got %d", http.StatusOK, w.Code) } if tt.wantError != (err != nil) { - t.Errorf("List() error = %v, wantError %v", err, tt.wantError) + t.Errorf("Data() error = %v, wantError %v", err, tt.wantError) } }) } From 998b5a68e1cf608a1fa015f9deeeae0599abe3a4 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Fri, 27 Oct 2023 20:49:05 +0800 Subject: [PATCH 4/8] save --- .../logging/client_interceptors.go | 10 +-- .../interceptors/logging/ctxlog/context.go | 67 +++++++------- .../interceptors/logging/ctxlog/fields.go | 10 +++ .../grpc/interceptors/logging/options.go | 88 +++++++++---------- .../logging/server_interceptors.go | 2 +- .../grpc/interceptors/request_tag/tags.go | 4 +- core/server/grpc/options.go | 5 +- core/server/grpc/server.go | 13 +-- core/server/grpc/service.go | 3 +- core/server/listener/server.go | 10 +-- core/server/server.go | 5 +- core/server/task/server.go | 9 +- pkg/config/config.go | 8 +- pkg/config/gormdb/gorm.go | 20 +++-- .../actions/authentic/control_gorm.go | 9 +- pkg/response/actions/authentic/control_mgm.go | 6 +- pkg/response/actions/authentic/delete_gorm.go | 3 +- pkg/response/actions/authentic/get_gorm.go | 3 +- pkg/response/actions/authentic/search_gorm.go | 9 +- pkg/response/actions/authentic/search_mgm.go | 12 ++- pkg/response/actions/virtual/create.go | 3 +- pkg/response/actions/virtual/delete.go | 3 +- pkg/response/actions/virtual/get.go | 3 +- pkg/response/api.go | 17 ++-- pkg/server/handler/handler.go | 6 +- 25 files changed, 165 insertions(+), 163 deletions(-) diff --git a/core/server/grpc/interceptors/logging/client_interceptors.go b/core/server/grpc/interceptors/logging/client_interceptors.go index c4bd360..39ebb88 100644 --- a/core/server/grpc/interceptors/logging/client_interceptors.go +++ b/core/server/grpc/interceptors/logging/client_interceptors.go @@ -9,10 +9,10 @@ package logging import ( "context" + "log/slog" "path" "time" - "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/logging/ctxlog" "google.golang.org/grpc" ) @@ -30,7 +30,7 @@ func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor { fields := newClientLoggerFields(ctx, method) start := time.Now() err := invoker(ctx, method, req, reply, cc, opts...) - logFinalClientLine(o, ctxlog.Extract(ctx).Fields(fields.Values()), start, err, + logFinalClientLine(o, ctxlog.Extract(ctx).With(fields.Args()...), start, err, "finished client unary call") return err } @@ -46,13 +46,13 @@ func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor { fieles := newClientLoggerFields(ctx, method) start := time.Now() clientStream, err := streamer(ctx, desc, cc, method, opts...) - logFinalClientLine(o, ctxlog.Extract(ctx).Fields(fieles.Values()), + logFinalClientLine(o, ctxlog.Extract(ctx).With(fieles.Args()...), start, err, "finished client streaming call") return clientStream, err } } -func logFinalClientLine(o *Options, l logger.Logger, start time.Time, err error, msg string) { +func logFinalClientLine(o *Options, l *slog.Logger, start time.Time, err error, msg string) { code := o.codeFunc(err) level := o.levelFunc(code) @@ -61,7 +61,7 @@ func logFinalClientLine(o *Options, l logger.Logger, start time.Time, err error, if err != nil { } - l.Fields(f.Values()).Log(level, msg, err) + l.With(f.Args()...).Log(context.Background(), level, msg, slog.Any("err", err)) } func newClientLoggerFields( diff --git a/core/server/grpc/interceptors/logging/ctxlog/context.go b/core/server/grpc/interceptors/logging/ctxlog/context.go index 4982a90..7afb968 100644 --- a/core/server/grpc/interceptors/logging/ctxlog/context.go +++ b/core/server/grpc/interceptors/logging/ctxlog/context.go @@ -2,17 +2,16 @@ package ctxlog import ( "context" + "log/slog" grpcCtxTags "github.com/grpc-ecosystem/go-grpc-middleware/tags" - "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" ) type ctxMarker struct{} type ctxLogger struct { - logger logger.Logger - fields map[string]interface{} + logger *slog.Logger + fields []any } var ( @@ -20,66 +19,68 @@ var ( ) // AddFields adds logger fields to the logger. -func AddFields(ctx context.Context, fields map[string]interface{}) { +func AddFields(ctx context.Context, fields ...any) { l, ok := ctx.Value(ctxMarkerKey).(*ctxLogger) if !ok || l == nil { return } - for k, v := range fields { - l.fields[k] = v + if l.fields == nil { + l.fields = make([]any, 0) } + l.fields = append(l.fields, fields...) } // Extract takes the call-scoped Log from grpc_logger middleware. // It always returns a Log that has all the grpc_ctxtags updated. -func Extract(ctx context.Context) logger.Logger { +func Extract(ctx context.Context) *slog.Logger { l, ok := ctx.Value(ctxMarkerKey).(*ctxLogger) if !ok || l == nil { - return logger.DefaultLogger + return slog.Default() } // Add grpc_ctxtags tags metadata until now. fields := TagsToFields(ctx) // Add logger fields added until now. - for k, v := range l.fields { - fields[k] = v - } - return l.logger.Fields(fields) + return l.logger.With(fields...) } // TagsToFields transforms the Tags on the supplied context into logger fields. -func TagsToFields(ctx context.Context) map[string]interface{} { - return grpcCtxTags.Extract(ctx).Values() +func TagsToFields(ctx context.Context) []any { + args := make([]any, 0) + for k, v := range grpcCtxTags.Extract(ctx).Values() { + args = append(args, k, v) + } + return args } -// ToContext adds the logger.Logger to the context for extraction later. +// ToContext adds the *slog.Logger to the context for extraction later. // Returning the new context that has been created. -func ToContext(ctx context.Context, logger logger.Logger) context.Context { +func ToContext(ctx context.Context, logger *slog.Logger) context.Context { l := &ctxLogger{ logger: logger, } return context.WithValue(ctx, ctxMarkerKey, l) } -// Debug is equivalent to calling Debug on the logger.Logger in the context. -// It is a no-op if the context does not contain a logger.Logger. -func Debug(ctx context.Context, msg string, fields map[string]interface{}) { - Extract(ctx).Fields(fields).Log(level.Debug, msg) +// Debug is equivalent to calling Debug on the *slog.Logger in the context. +// It is a no-op if the context does not contain a *slog.Logger. +func Debug(ctx context.Context, msg string, fields ...any) { + Extract(ctx).With(fields...).Log(ctx, slog.LevelDebug, msg) } -// Info is equivalent to calling Info on the logger.Logger in the context. -// It is a no-op if the context does not contain a logger.Logger. -func Info(ctx context.Context, msg string, fields map[string]interface{}) { - Extract(ctx).Fields(fields).Log(level.Info, msg) +// Info is equivalent to calling Info on the *slog.Logger in the context. +// It is a no-op if the context does not contain a *slog.Logger. +func Info(ctx context.Context, msg string, fields ...any) { + Extract(ctx).With(fields...).Log(ctx, slog.LevelInfo, msg) } -// Warn is equivalent to calling Warn on the logger.Logger in the context. -// It is a no-op if the context does not contain a logger.Logger. -func Warn(ctx context.Context, msg string, fields map[string]interface{}) { - Extract(ctx).Fields(fields).Log(level.Warn, msg) +// Warn is equivalent to calling Warn on the *slog.Logger in the context. +// It is a no-op if the context does not contain a *slog.Logger. +func Warn(ctx context.Context, msg string, fields ...any) { + Extract(ctx).With(fields...).Log(ctx, slog.LevelWarn, msg) } -// Error is equivalent to calling Error on the logger.Logger in the context. -// It is a no-op if the context does not contain a logger.Logger. -func Error(ctx context.Context, msg string, fields map[string]interface{}) { - Extract(ctx).Fields(fields).Log(level.Error, msg) +// Error is equivalent to calling Error on the *slog.Logger in the context. +// It is a no-op if the context does not contain a *slog.Logger. +func Error(ctx context.Context, msg string, fields ...any) { + Extract(ctx).With(fields...).Log(ctx, slog.LevelError, msg) } diff --git a/core/server/grpc/interceptors/logging/ctxlog/fields.go b/core/server/grpc/interceptors/logging/ctxlog/fields.go index 745ac46..53f447a 100644 --- a/core/server/grpc/interceptors/logging/ctxlog/fields.go +++ b/core/server/grpc/interceptors/logging/ctxlog/fields.go @@ -36,6 +36,16 @@ func (e *Fields) Values() map[string]interface{} { return result } +// Args return args +func (e *Fields) Args() []any { + args := make([]any, 0) + e.value.Range(func(key, value interface{}) bool { + args = append(args, key, value) + return true + }) + return args +} + // Merge merge fields func (e *Fields) Merge(f *Fields) { for k, v := range f.Values() { diff --git a/core/server/grpc/interceptors/logging/options.go b/core/server/grpc/interceptors/logging/options.go index 889919b..620c224 100644 --- a/core/server/grpc/interceptors/logging/options.go +++ b/core/server/grpc/interceptors/logging/options.go @@ -9,10 +9,10 @@ package logging import ( "context" + "log/slog" "time" grpcLogging "github.com/grpc-ecosystem/go-grpc-middleware/logging" - "github.com/mss-boot-io/mss-boot/core/logger/level" "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/logging/ctxlog" "google.golang.org/grpc/codes" ) @@ -41,8 +41,8 @@ type Options struct { // Option set Options type Option func(*Options) -// CodeToLevel function defines the mapping between gRPC return codes and interceptor log level. -type CodeToLevel func(code codes.Code) level.Level +// CodeToLevel function defines the mapping between gRPC return codes and interceptor log slog.Level +type CodeToLevel func(code codes.Code) slog.Level // DurationToField function defines how to produce duration fields for logging type DurationToField func(duration time.Duration) ctxlog.Fields @@ -90,7 +90,7 @@ func WithTimestampFormat(format string) Option { } // MessageProducer produces a user defined log message -type MessageProducer func(ctx context.Context, msg string, level level.Level, code codes.Code, err error, duration *ctxlog.Fields) +type MessageProducer func(ctx context.Context, msg string, level slog.Level, code codes.Code, err error, duration *ctxlog.Fields) func evaluateServerOpt(opts []Option) *Options { optCopy := &Options{} @@ -113,86 +113,86 @@ func evaluateClientOpt(opts []Option) *Options { } // DefaultCodeToLevel is the default implementation of gRPC return codes and interceptor log level for server side. -func DefaultCodeToLevel(code codes.Code) level.Level { +func DefaultCodeToLevel(code codes.Code) slog.Level { switch code { case codes.OK: - return level.Info + return slog.LevelInfo case codes.Canceled: - return level.Info + return slog.LevelInfo case codes.Unknown: - return level.Error + return slog.LevelError case codes.InvalidArgument: - return level.Info + return slog.LevelInfo case codes.DeadlineExceeded: - return level.Warn + return slog.LevelWarn case codes.NotFound: - return level.Info + return slog.LevelInfo case codes.AlreadyExists: - return level.Info + return slog.LevelInfo case codes.PermissionDenied: - return level.Warn + return slog.LevelWarn case codes.Unauthenticated: - return level.Info // unauthenticated requests can happen + return slog.LevelInfo // unauthenticated requests can happen case codes.ResourceExhausted: - return level.Warn + return slog.LevelWarn case codes.FailedPrecondition: - return level.Warn + return slog.LevelWarn case codes.Aborted: - return level.Warn + return slog.LevelWarn case codes.OutOfRange: - return level.Warn + return slog.LevelWarn case codes.Unimplemented: - return level.Error + return slog.LevelError case codes.Internal: - return level.Error + return slog.LevelError case codes.Unavailable: - return level.Warn + return slog.LevelWarn case codes.DataLoss: - return level.Error + return slog.LevelError default: - return level.Error + return slog.LevelError } } // DefaultClientCodeToLevel is the default implementation of gRPC return codes to log levels for client side. -func DefaultClientCodeToLevel(code codes.Code) level.Level { +func DefaultClientCodeToLevel(code codes.Code) slog.Level { switch code { case codes.OK: - return level.Debug + return slog.LevelDebug case codes.Canceled: - return level.Debug + return slog.LevelDebug case codes.Unknown: - return level.Info + return slog.LevelInfo case codes.InvalidArgument: - return level.Debug + return slog.LevelDebug case codes.DeadlineExceeded: - return level.Info + return slog.LevelInfo case codes.NotFound: - return level.Debug + return slog.LevelDebug case codes.AlreadyExists: - return level.Debug + return slog.LevelDebug case codes.PermissionDenied: - return level.Info + return slog.LevelInfo case codes.Unauthenticated: - return level.Info // unauthenticated requests can happen + return slog.LevelInfo // unauthenticated requests can happen case codes.ResourceExhausted: - return level.Debug + return slog.LevelDebug case codes.FailedPrecondition: - return level.Debug + return slog.LevelDebug case codes.Aborted: - return level.Debug + return slog.LevelDebug case codes.OutOfRange: - return level.Debug + return slog.LevelDebug case codes.Unimplemented: - return level.Warn + return slog.LevelWarn case codes.Internal: - return level.Warn + return slog.LevelWarn case codes.Unavailable: - return level.Warn + return slog.LevelWarn case codes.DataLoss: - return level.Warn + return slog.LevelWarn default: - return level.Info + return slog.LevelInfo } } @@ -215,12 +215,12 @@ func durationToMilliseconds(duration time.Duration) float32 { } // DefaultMessageProducer writes the default message -func DefaultMessageProducer(ctx context.Context, msg string, level level.Level, code codes.Code, err error, duration *ctxlog.Fields) { +func DefaultMessageProducer(ctx context.Context, msg string, level slog.Level, code codes.Code, err error, duration *ctxlog.Fields) { // re-extract logger from newCtx, as it may have extra fields that changed in the holder. fields := duration fields.Set("grpc.code", code.String()) if err != nil { fields.Set("grpc.error", err) } - ctxlog.Extract(ctx).Fields(fields.Values()).Log(level, msg) + ctxlog.Extract(ctx).With(fields.Args()...).Log(ctx, level, msg) } diff --git a/core/server/grpc/interceptors/logging/server_interceptors.go b/core/server/grpc/interceptors/logging/server_interceptors.go index f194812..769f9fd 100644 --- a/core/server/grpc/interceptors/logging/server_interceptors.go +++ b/core/server/grpc/interceptors/logging/server_interceptors.go @@ -80,7 +80,7 @@ func newLoggerForCall(ctx context.Context, fullMethodString string, start time.T } requestID := utils.GetRequestID(ctx) f.Set(utils.RequestIDKey, requestID) - callLog := ctxlog.Extract(ctx).Fields(f.Values()) + callLog := ctxlog.Extract(ctx).With(f.Args()...) ctx = metadata.AppendToOutgoingContext( ctx, utils.RequestIDKey, requestID, diff --git a/core/server/grpc/interceptors/request_tag/tags.go b/core/server/grpc/interceptors/request_tag/tags.go index 7b0494e..8feb21e 100644 --- a/core/server/grpc/interceptors/request_tag/tags.go +++ b/core/server/grpc/interceptors/request_tag/tags.go @@ -10,7 +10,7 @@ package requesttag import ( "context" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/mss-boot-io/mss-boot/core/tools/utils" "google.golang.org/grpc" "google.golang.org/grpc/metadata" @@ -35,7 +35,7 @@ func StreamServerInterceptor() grpc.StreamServerInterceptor { stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - wrappedStream := grpc_middleware.WrapServerStream(stream) + wrappedStream := grpcMiddleware.WrapServerStream(stream) wrappedStream.WrappedContext = AppendTagsForContext(stream.Context()) return handler(srv, wrappedStream) } diff --git a/core/server/grpc/options.go b/core/server/grpc/options.go index 1da1cea..5f72c84 100644 --- a/core/server/grpc/options.go +++ b/core/server/grpc/options.go @@ -10,6 +10,8 @@ package grpc import ( "context" "crypto/tls" + "fmt" + "log/slog" "math" "time" @@ -18,7 +20,6 @@ import ( opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing" prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/mss-boot-io/mss-boot/core/errcode" - log "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/logging" requesttag "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/request_tag" "google.golang.org/grpc" @@ -198,7 +199,7 @@ func defaultOptions() *Options { // customRecovery custom recovery func customRecovery(id, domain string) recovery.RecoveryHandlerFunc { return func(p interface{}) (err error) { - log.Errorf("panic triggered: %v", p) + slog.Error(fmt.Sprintf("panic triggered: %v", p)) return errcode.New(id, domain, errcode.GRPCInternalServerError) } } diff --git a/core/server/grpc/server.go b/core/server/grpc/server.go index d3878f3..8c2108c 100644 --- a/core/server/grpc/server.go +++ b/core/server/grpc/server.go @@ -11,12 +11,14 @@ import ( "context" "errors" "fmt" + "log" + "log/slog" "net" + "os" "sync" middleware "github.com/grpc-ecosystem/go-grpc-middleware" prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - log "github.com/mss-boot-io/mss-boot/core/logger" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" @@ -91,7 +93,8 @@ func (e *Server) initGrpcServerOptions() []grpc.ServerOption { if e.options.certFile != "" && e.options.keyFile != "" { creds, err := credentials.NewServerTLSFromFile(e.options.certFile, e.options.keyFile) if err != nil { - log.Fatalf("Failed to generate credentials %v", err) + slog.Error("Failed to generate credentials", slog.Any("err", err)) + os.Exit(-1) } opts = append(opts, grpc.Creds(creds)) } @@ -116,11 +119,11 @@ func (e *Server) Start(ctx context.Context) error { if err != nil { return fmt.Errorf("gRPC Server listening on %s failed: %w", e.options.addr, err) } - log.Infof("gRPC Server listening on %s", ts.Addr().String()) + log.Printf("gRPC Server listening on %s\n", ts.Addr().String()) go func() { if err = e.srv.Serve(ts); err != nil { - log.Errorf("gRPC Server start error: %s", err.Error()) + slog.ErrorContext(ctx, "gRPC Server start error", slog.Any("err", err)) } }() e.started = true @@ -131,7 +134,7 @@ func (e *Server) Start(ctx context.Context) error { // Shutdown shutdown func (e *Server) Shutdown(ctx context.Context) error { <-ctx.Done() - log.Info("gRPC Server will be shutdown gracefully") + slog.InfoContext(ctx, "gRPC Server will be shutdown gracefully") e.srv.GracefulStop() return nil } diff --git a/core/server/grpc/service.go b/core/server/grpc/service.go index eff9995..eb2a3cd 100644 --- a/core/server/grpc/service.go +++ b/core/server/grpc/service.go @@ -18,6 +18,7 @@ import ( "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/logging" reqtags "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/request_tag" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) // Service service client @@ -41,7 +42,7 @@ func (e *Service) Dial( } e.Connection, err = grpc.DialContext(ctx, endpoint, - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithStreamInterceptor(middleware.ChainStreamClient(defaultStreamClientInterceptors()...)), grpc.WithUnaryInterceptor(middleware.ChainUnaryClient(unary...)), grpc.WithDefaultCallOptions(grpc.WaitForReady(true), grpc.MaxCallRecvMsgSize(defaultMaxMsgSize)), diff --git a/core/server/listener/server.go b/core/server/listener/server.go index 2267156..c02c2c9 100644 --- a/core/server/listener/server.go +++ b/core/server/listener/server.go @@ -9,11 +9,11 @@ package listener import ( "context" + "log/slog" "net" "net/http" _ "net/http/pprof" - log "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/core/server" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -85,21 +85,21 @@ func (e *Server) Start(ctx context.Context) error { e.srv.BaseContext = func(_ net.Listener) context.Context { return ctx } - log.Infof("%s Server listening on %s", e.opts.name, l.Addr().String()) + slog.InfoContext(ctx, e.opts.name+" Server listening on "+l.Addr().String()) go func() { if e.opts.keyFile == "" || e.opts.certFile == "" { if err = e.srv.Serve(l); err != nil { - log.Errorf("%s Server start error: %s", e.opts.name, err.Error()) + slog.ErrorContext(ctx, e.opts.name+" Server start error", slog.Any("err", err.Error())) } } else { if err = e.srv.ServeTLS(l, e.opts.certFile, e.opts.keyFile); err != nil { - log.Errorf("%s Server start error: %s", e.opts.name, err.Error()) + slog.ErrorContext(ctx, e.opts.name+" Server start error", slog.Any("err", err.Error())) } } <-ctx.Done() err = e.Shutdown(ctx) if err != nil { - log.Errorf("%S Server shutdown error: %s", e.opts.name, err.Error()) + slog.ErrorContext(ctx, e.opts.name+" Server shutdown error", slog.Any("err", err.Error())) } }() if e.opts.startedHook != nil { diff --git a/core/server/server.go b/core/server/server.go index 558e9e2..4cafcf0 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -11,9 +11,8 @@ import ( "context" "errors" "fmt" + "log/slog" "sync" - - log "github.com/mss-boot-io/mss-boot/core/logger" ) // Server server @@ -123,7 +122,7 @@ func (e *Server) engageStopProcedure(stopComplete <-chan struct{}) error { select { case err, ok := <-e.errChan: if ok { - log.Error(err, "error received after stop sequence was engaged") + slog.Error("error received after stop sequence was engaged", slog.Any("err", err)) } case <-stopComplete: return diff --git a/core/server/task/server.go b/core/server/task/server.go index 845188c..7e4154d 100644 --- a/core/server/task/server.go +++ b/core/server/task/server.go @@ -9,10 +9,9 @@ package task import ( "context" + "log/slog" "github.com/robfig/cron/v3" - - log "github.com/mss-boot-io/mss-boot/core/logger" ) var task = &Server{ @@ -52,7 +51,7 @@ func UpdateJob(key string, spec string, job cron.Job) error { } entryID, err := task.opts.task.AddJob(spec, job) if err != nil { - log.Errorf("task add job error: %s", err.Error()) + slog.Error("task add job error", slog.Any("err", err)) return err } task.opts.schedules[key] = schedule{ @@ -95,7 +94,7 @@ func (e *Server) Start(ctx context.Context) error { for i, s := range e.opts.schedules { s.entryID, err = e.opts.task.AddJob(e.opts.schedules[i].spec, e.opts.schedules[i].job) if err != nil { - log.Errorf("task add job error: %s", err.Error()) + slog.ErrorContext(ctx, "task add job error", slog.Any("err", err)) return err } e.opts.schedules[i] = s @@ -105,7 +104,7 @@ func (e *Server) Start(ctx context.Context) error { <-ctx.Done() err = e.Shutdown(ctx) if err != nil { - log.Errorf("%S Server shutdown error: %s", e.String(), err.Error()) + slog.ErrorContext(ctx, e.String()+" Server shutdown error", slog.Any("err", err.Error())) } }() return nil diff --git a/pkg/config/config.go b/pkg/config/config.go index 9bfd593..e295be8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,9 +10,9 @@ package config import ( "encoding/json" "fmt" + "log/slog" "os" - log "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/pkg/config/source" sourceFS "github.com/mss-boot-io/mss-boot/pkg/config/source/fs" sourceLocal "github.com/mss-boot-io/mss-boot/pkg/config/source/local" @@ -67,7 +67,7 @@ func Init(cfg any, options ...source.Option) (err error) { var rb []byte rb, err = f.ReadFile(opts.Name) if err != nil { - log.Errorf("read file error: %v", err) + slog.Error(err.Error()) return err } var unm func([]byte, interface{}) error @@ -79,7 +79,7 @@ func Init(cfg any, options ...source.Option) (err error) { } err = unm(rb, cfg) if err != nil { - log.Errorf("unmarshal error: %v", err) + slog.Error(err.Error()) return err } @@ -87,7 +87,7 @@ func Init(cfg any, options ...source.Option) (err error) { if err == nil { err = unm(rb, cfg) if err != nil { - log.Errorf("unmarshal error: %v", err) + slog.Error(err.Error()) } } return nil diff --git a/pkg/config/gormdb/gorm.go b/pkg/config/gormdb/gorm.go index 476be18..0bb510f 100644 --- a/pkg/config/gormdb/gorm.go +++ b/pkg/config/gormdb/gorm.go @@ -12,11 +12,12 @@ import ( "github.com/casbin/casbin/v2/model" "github.com/casbin/casbin/v2/persist" gormadapter "github.com/casbin/gorm-adapter/v3" - log "github.com/mss-boot-io/mss-boot/core/logger" gormLogger "github.com/mss-boot-io/mss-boot/pkg/config/gormdb/logger" "gorm.io/gorm" "gorm.io/gorm/logger" "gorm.io/gorm/schema" + "log/slog" + "os" ) // DB gorm db @@ -84,12 +85,14 @@ func (e *Database) Init() { //SlowThreshold: time.Second, Colorful: true, LogLevel: logger.LogLevel( + log.DefaultLogger.Options().Level.ToGorm()), }, ), }, opens[e.Driver]) if err != nil { - log.Fatalf("%s connect error : %s", e.Driver, err.Error()) + slog.Error(e.Driver+" connect failed", slog.Any("err", err)) + os.Exit(-1) } // casbin if e.CasbinModel != "" { @@ -97,20 +100,25 @@ func (e *Database) Init() { var a persist.Adapter a, err = gormadapter.NewAdapterByDBUseTableName(DB, "mss_boot", "casbin_rule") if err != nil { - log.Fatalf("gormadapter.NewAdapterByDB error : %s", err.Error()) + slog.Error("gormadapter.NewAdapterByDB error", slog.Any("err", err)) + os.Exit(-1) } var m model.Model m, err = model.NewModelFromString(e.CasbinModel) if err != nil { - log.Fatalf("model.NewModelFromString error : %s", err.Error()) + slog.Error("model.NewModelFromString error", slog.Any("err", err)) + os.Exit(-1) } Enforcer, err = casbin.NewEnforcer(m, a) if err != nil { - log.Fatalf("casbin.NewEnforcer error : %s", err.Error()) + slog.Error("casbin.NewEnforcer error", slog.Any("err", err)) + os.Exit(-1) } err = Enforcer.LoadPolicy() if err != nil { - log.Fatalf("Enforcer.LoadPolicy error : %s", err.Error()) + slog.Error("Enforcer.LoadPolicy error", slog.Any("err", err)) + os.Exit(-1) + slog.Default() } Enforcer.EnableAutoSave(true) Enforcer.EnableAutoBuildRoleLinks(true) diff --git a/pkg/response/actions/authentic/control_gorm.go b/pkg/response/actions/authentic/control_gorm.go index 6fa7cd8..18aa91a 100644 --- a/pkg/response/actions/authentic/control_gorm.go +++ b/pkg/response/actions/authentic/control_gorm.go @@ -38,8 +38,7 @@ func (e *Control) createGorm(c *gin.Context) { } err := gormdb.DB.Create(m).Error if err != nil { - api.Log.Error(err) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Create error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -63,8 +62,7 @@ func (e *Control) updateGorm(c *gin.Context) { api.Err(http.StatusNotFound) return } - api.Log.Error(err) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Update error", "error", err.Error()) api.Err(http.StatusInternalServerError) return } @@ -76,8 +74,7 @@ func (e *Control) updateGorm(c *gin.Context) { } err = gormdb.DB.Save(m).Error if err != nil { - api.Log.Error(err) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Update error", "error", err.Error()) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/authentic/control_mgm.go b/pkg/response/actions/authentic/control_mgm.go index c0afb33..ddd6599 100644 --- a/pkg/response/actions/authentic/control_mgm.go +++ b/pkg/response/actions/authentic/control_mgm.go @@ -80,8 +80,7 @@ func (e *Control) createMongo(c *gin.Context) { } err := mgm.Coll(e.ModelMgm).CreateWithCtx(c, m) if err != nil { - api.Log.Error(err) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Create error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -104,12 +103,11 @@ func (e *Control) updateMongo(c *gin.Context) { m.SetID(id) err = mgm.Coll(e.ModelMgm).UpdateWithCtx(c, m) if err != nil { - api.AddError(err) if errors.Is(err, mongo.ErrNoDocuments) { api.Err(http.StatusNotFound) return } - api.Log.Error(err) + api.AddError(err).Log.ErrorContext(c, "Update error", "error", err) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/authentic/delete_gorm.go b/pkg/response/actions/authentic/delete_gorm.go index e9d10d1..9455598 100644 --- a/pkg/response/actions/authentic/delete_gorm.go +++ b/pkg/response/actions/authentic/delete_gorm.go @@ -33,8 +33,7 @@ func (e *Delete) deleteGorm(c *gin.Context, ids ...string) { } err := gormdb.DB.Delete(e.ModelGorm, ids).Error if err != nil { - api.Log.Error(err) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Delete error", "error", err) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/authentic/get_gorm.go b/pkg/response/actions/authentic/get_gorm.go index ab43926..58ff9f3 100644 --- a/pkg/response/actions/authentic/get_gorm.go +++ b/pkg/response/actions/authentic/get_gorm.go @@ -39,8 +39,7 @@ func (e *Get) getGorm(c *gin.Context, key string) { api.Err(http.StatusNotFound) return } - api.Log.Error(err) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Get error", "error", err) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/authentic/search_gorm.go b/pkg/response/actions/authentic/search_gorm.go index 3446bc6..493583d 100644 --- a/pkg/response/actions/authentic/search_gorm.go +++ b/pkg/response/actions/authentic/search_gorm.go @@ -46,8 +46,7 @@ func (e *Search) searchGorm(c *gin.Context) { ) rows, err := query.Rows() if err != nil { - api.Log.Errorf("Search error: %s", err.Error()) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Search error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -57,8 +56,7 @@ func (e *Search) searchGorm(c *gin.Context) { m = pkg.TablerDeepCopy(e.ModelGorm) err = db.ScanRows(rows, m) if err != nil { - api.Log.Errorf("Search error: %s", err.Error()) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Search error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -66,8 +64,7 @@ func (e *Search) searchGorm(c *gin.Context) { } err = query.Limit(-1).Offset(-1).Count(&count).Error if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - api.Log.Errorf("Search error: %s", err.Error()) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "Search error", "error", err) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/authentic/search_mgm.go b/pkg/response/actions/authentic/search_mgm.go index 3358436..3627e3d 100644 --- a/pkg/response/actions/authentic/search_mgm.go +++ b/pkg/response/actions/authentic/search_mgm.go @@ -96,8 +96,7 @@ func (e *Search) searchMgm(c *gin.Context) { count, err := mgm.Coll(e.ModelMgm).CountDocuments(c, filter) if err != nil { - api.Log.Errorf("count items error, %s", err.Error()) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "count items error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -112,7 +111,7 @@ func (e *Search) searchMgm(c *gin.Context) { result, err := mgm.Coll(e.ModelMgm).Find(c, filter, ops) if err != nil { - api.AddError(err).Log.Errorf("find items error, %s", err.Error()) + api.AddError(err).Log.ErrorContext(c, "find items error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -122,7 +121,7 @@ func (e *Search) searchMgm(c *gin.Context) { m := pkg.ModelDeepCopy(e.ModelMgm) err = result.Decode(m) if err != nil { - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "decode items error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -153,8 +152,7 @@ func (e *Search) searchMgm(c *gin.Context) { }) result, err := mgm.Coll(e.ModelMgm).Aggregate(c, pipeline) if err != nil { - api.Log.Errorf("find items error, %s", err.Error()) - api.AddError(err) + api.AddError(err).Log.ErrorContext(c, "find items error", "error", err) api.Err(http.StatusInternalServerError) return } @@ -175,7 +173,7 @@ func (e *Search) searchMgm(c *gin.Context) { //todo bson.M to model err = BsonMTransferModel(bm, m) if err != nil { - api.AddError(err).Log.Errorf("transfer bson.M to model error, %s", err.Error()) + api.AddError(err).Log.ErrorContext(c, "transfer bson.M to model error", "error", err) return } items = append(items, m) diff --git a/pkg/response/actions/virtual/create.go b/pkg/response/actions/virtual/create.go index 8fe55fc..3c3a69e 100644 --- a/pkg/response/actions/virtual/create.go +++ b/pkg/response/actions/virtual/create.go @@ -53,8 +53,7 @@ func (e *Create) Handler() gin.HandlerFunc { return } if err := gormdb.DB.Scopes(m.TableScope).Create(req).Error; err != nil { - api.AddError(err) - api.Log.Errorf("create %s error", c.Param(PathKey)) + api.AddError(err).Log.ErrorContext(c, "create error", PathKey, c.Param(PathKey)) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/virtual/delete.go b/pkg/response/actions/virtual/delete.go index f742d58..760eac8 100644 --- a/pkg/response/actions/virtual/delete.go +++ b/pkg/response/actions/virtual/delete.go @@ -59,8 +59,7 @@ func (e *Delete) Handler() gin.HandlerFunc { api.Err(http.StatusNotFound) return } - api.AddError(err) - api.Log.Errorf("delete %s error", c.Param(PathKey)) + api.AddError(err).Log.ErrorContext(c, "delete error", PathKey, c.Param(PathKey)) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/virtual/get.go b/pkg/response/actions/virtual/get.go index 3f3e0c2..a45c14e 100644 --- a/pkg/response/actions/virtual/get.go +++ b/pkg/response/actions/virtual/get.go @@ -58,8 +58,7 @@ func (e *Get) Handler() gin.HandlerFunc { api.Err(http.StatusNotFound) return } - api.AddError(err) - api.Log.Errorf("get %s error", c.Param(PathKey)) + api.AddError(err).Log.ErrorContext(c, "get error", PathKey, c.Param(PathKey)) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/api.go b/pkg/response/api.go index fc5878b..c1e2adb 100644 --- a/pkg/response/api.go +++ b/pkg/response/api.go @@ -10,6 +10,7 @@ package response import ( "errors" "fmt" + "log/slog" "net/http" "strings" @@ -17,7 +18,6 @@ import ( "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" - "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/pkg" "github.com/mss-boot-io/mss-boot/pkg/language" ) @@ -31,7 +31,7 @@ var AuthHandler gin.HandlerFunc // API api接口 type API struct { Context *gin.Context - Log *logger.Helper + Log *slog.Logger Error error engine *gin.RouterGroup } @@ -209,19 +209,14 @@ func (e *API) getAcceptLanguage() string { } // GetRequestLogger 获取上下文提供的日志 -func GetRequestLogger(c *gin.Context) *logger.Helper { - var log *logger.Helper - l, ok := c.Get(pkg.LoggerKey) - if ok { - log, ok = l.(*logger.Helper) +func GetRequestLogger(c *gin.Context) *slog.Logger { + if l, exist := c.Get(pkg.LoggerKey); exist { + log, ok := l.(*slog.Logger) if ok && log != nil { return log } } //如果没有在上下文中放入logger requestID := pkg.GenerateMsgIDFromContext(c) - log = logger.NewHelper(logger.DefaultLogger).WithFields(map[string]interface{}{ - strings.ToLower(pkg.TrafficKey): requestID, - }) - return log + return slog.Default().With(strings.ToLower(pkg.TrafficKey), requestID) } diff --git a/pkg/server/handler/handler.go b/pkg/server/handler/handler.go index da62fb0..ff1956e 100644 --- a/pkg/server/handler/handler.go +++ b/pkg/server/handler/handler.go @@ -9,8 +9,8 @@ package handler import ( "context" + "log/slog" - "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/core/server/grpc/interceptors/logging/ctxlog" "github.com/mss-boot-io/mss-boot/core/tools/utils" ) @@ -19,12 +19,12 @@ import ( type Handler struct { ID string RequestID string - Log *logger.Helper + Log *slog.Logger } // Make 构建 func (e *Handler) Make(c context.Context) { - e.Log = logger.NewHelper(ctxlog.Extract(c)) + e.Log = ctxlog.Extract(c) e.RequestID = utils.GetRequestID(c) } From e536c53cdd33caac914a1b60a4c517cf4692b618 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Fri, 27 Oct 2023 23:35:16 +0800 Subject: [PATCH 5/8] save --- go.mod | 4 +-- go.sum | 16 +++++++++++ pkg/config/gormdb/gorm.go | 11 +------- pkg/config/logger.go | 58 ++++++++++++--------------------------- 4 files changed, 36 insertions(+), 53 deletions(-) diff --git a/go.mod b/go.mod index c004717..e11ef9d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/mss-boot-io/mss-boot -go 1.20 +go 1.21 require ( github.com/aws/aws-sdk-go-v2 v1.21.0 @@ -70,7 +70,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.13.6 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect - github.com/aws/smithy-go v1.14.2 // indirect + github.com/aws/smithy-go v1.14.2 github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index f67eed1..393f60f 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,23 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/agiledragon/gomonkey/v2 v2.2.0 h1:QJWqpdEhGV/JJy70sZ/LDnhbSlMrqHAWHcNOjz1kyuI= +github.com/agiledragon/gomonkey/v2 v2.2.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0= @@ -92,6 +97,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -107,6 +113,7 @@ github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxF github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -125,6 +132,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= @@ -151,8 +159,10 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -205,14 +215,17 @@ github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgSh github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= @@ -258,6 +271,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -321,6 +335,7 @@ go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -462,6 +477,7 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/config/gormdb/gorm.go b/pkg/config/gormdb/gorm.go index 0bb510f..2ac47b7 100644 --- a/pkg/config/gormdb/gorm.go +++ b/pkg/config/gormdb/gorm.go @@ -12,7 +12,6 @@ import ( "github.com/casbin/casbin/v2/model" "github.com/casbin/casbin/v2/persist" gormadapter "github.com/casbin/gorm-adapter/v3" - gormLogger "github.com/mss-boot-io/mss-boot/pkg/config/gormdb/logger" "gorm.io/gorm" "gorm.io/gorm/logger" "gorm.io/gorm/schema" @@ -80,15 +79,7 @@ func (e *Database) Init() { NamingStrategy: schema.NamingStrategy{ SingularTable: true, }, - Logger: gormLogger.New( - logger.Config{ - //SlowThreshold: time.Second, - Colorful: true, - LogLevel: logger.LogLevel( - - log.DefaultLogger.Options().Level.ToGorm()), - }, - ), + Logger: logger.Default, }, opens[e.Driver]) if err != nil { slog.Error(e.Driver+" connect failed", slog.Any("err", err)) diff --git a/pkg/config/logger.go b/pkg/config/logger.go index 8cc85c3..594c211 100644 --- a/pkg/config/logger.go +++ b/pkg/config/logger.go @@ -10,25 +10,20 @@ package config import ( "io" "log" + "log/slog" "os" - "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" "github.com/mss-boot-io/mss-boot/core/logger/writer" - "github.com/mss-boot-io/mss-boot/core/plugins/logger/logrus" - "github.com/mss-boot-io/mss-boot/core/plugins/logger/zap" - logrusCore "github.com/sirupsen/logrus" - "go.uber.org/zap/zapcore" ) // Logger logger配置 type Logger struct { - Type string `yaml:"type" json:"type"` - Path string `yaml:"path" json:"path"` - Level string `yaml:"level" json:"level"` - Stdout string `yaml:"stdout" json:"stdout"` - Cap uint `yaml:"cap" json:"cap"` - Formatter string `yaml:"formatter" json:"formatter"` + Path string `yaml:"path" json:"path"` + Level slog.Level `yaml:"level" json:"level"` + Stdout string `yaml:"stdout" json:"stdout"` + AddSource bool `yaml:"addSource" json:"addSource"` + Cap uint `yaml:"cap" json:"cap"` + Json bool `yaml:"json" json:"json"` } // Init 初始化日志 @@ -54,37 +49,18 @@ func (e *Logger) Init() { default: output = os.Stderr } - var l level.Level - l, err = level.GetLevel(e.Level) - if err != nil { - log.Fatalf("get logger level error, %s", err.Error()) + if e.Json { + slog.SetDefault(slog.New(slog.NewJSONHandler(output, &slog.HandlerOptions{ + AddSource: e.AddSource, + Level: e.Level, + }))) + return } - opts := []logger.Option{ - logger.WithLevel(l), - logger.WithOutput(output), - } - switch e.Type { - case "zap": - opts = append(opts, zap.WithCallerSkip(2)) - switch e.Formatter { - case "json": - opts = append(opts, zap.WithEncoder(zapcore.NewJSONEncoder(zapcore.EncoderConfig{}))) - } - logger.DefaultLogger, err = zap.NewLogger(opts...) - if err != nil { - log.Fatalf("new zap logger error, %s", err.Error()) - } - case "logrus": - opts = append(opts, logrus.WithSkip(12), logrus.ReportCaller()) - switch e.Formatter { - case "json": - opts = append(opts, logrus.WithJSONFormatter(&logrusCore.JSONFormatter{})) - } - logger.DefaultLogger = logrus.NewLogger(opts...) - default: - logger.DefaultLogger = logger.NewLogger(opts...) - } + slog.SetDefault(slog.New(slog.NewTextHandler(output, &slog.HandlerOptions{ + AddSource: e.AddSource, + Level: e.Level, + }))) } func pathCreate(dir string) error { From 425ab97f573f1b90e31b4d1de89db1bd9800aa21 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Sun, 29 Oct 2023 22:06:08 +0800 Subject: [PATCH 6/8] :sparkles: feat: support gorm logger --- pkg/config/logger.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/config/logger.go b/pkg/config/logger.go index 594c211..918b3ad 100644 --- a/pkg/config/logger.go +++ b/pkg/config/logger.go @@ -12,6 +12,9 @@ import ( "log" "log/slog" "os" + "time" + + "gorm.io/gorm/logger" "github.com/mss-boot-io/mss-boot/core/logger/writer" ) @@ -61,6 +64,28 @@ func (e *Logger) Init() { AddSource: e.AddSource, Level: e.Level, }))) + + // set gorm default logger + logger.Default = logger.New(log.New(output, "\r\n", log.LstdFlags), logger.Config{ + SlowThreshold: 200 * time.Millisecond, + LogLevel: e.GormLevel(), + IgnoreRecordNotFoundError: false, + Colorful: true, + }) + +} + +func (e *Logger) GormLevel() logger.LogLevel { + switch e.Level { + case slog.LevelDebug, slog.LevelInfo: + return logger.Info + case slog.LevelWarn: + return logger.Warn + case slog.LevelError: + return logger.Error + default: + return logger.Silent + } } func pathCreate(dir string) error { From 450645776698e93c71bce39aa568cef67c973c45 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Sun, 29 Oct 2023 23:19:55 +0800 Subject: [PATCH 7/8] :arrow_up: update go version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05b9641..579ec45 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.21' cache: false - uses: actions/checkout@v3 - name: install deps From 2b3fcc089b3b0b07ef99ada3823e28c39568efc6 Mon Sep 17 00:00:00 2001 From: lwnmengjing Date: Sun, 29 Oct 2023 23:38:39 +0800 Subject: [PATCH 8/8] :sparkles: feat: delete logger --- core/logger/default.go | 192 ------------------ core/logger/default_test.go | 43 ---- core/logger/formatter/formatter.go | 53 ----- core/logger/formatter/options.go | 71 ------- core/logger/helper.go | 133 ------------ core/logger/level/level.go | 73 ------- core/logger/level/level_string.go | 29 --- core/logger/logger.go | 119 ----------- core/logger/options.go | 72 ------- core/plugins/logger/logrus/README.md | 25 --- core/plugins/logger/logrus/logrus.go | 169 --------------- core/plugins/logger/logrus/logrus_test.go | 82 -------- core/plugins/logger/logrus/options.go | 83 -------- core/plugins/logger/zap/options.go | 57 ------ core/plugins/logger/zap/zap.go | 237 ---------------------- core/plugins/logger/zap/zap_test.go | 116 ----------- pkg/config/gormdb/logger/logger.go | 171 ---------------- pkg/config/gormdb/logger/logger_test.go | 20 -- pkg/config/tls.go | 9 +- pkg/response/actions/virtual/search.go | 3 +- pkg/response/actions/virtual/update.go | 3 +- pkg/response/return.go | 6 +- 22 files changed, 10 insertions(+), 1756 deletions(-) delete mode 100644 core/logger/default.go delete mode 100644 core/logger/default_test.go delete mode 100644 core/logger/formatter/formatter.go delete mode 100644 core/logger/formatter/options.go delete mode 100644 core/logger/helper.go delete mode 100644 core/logger/level/level.go delete mode 100644 core/logger/level/level_string.go delete mode 100644 core/logger/logger.go delete mode 100644 core/logger/options.go delete mode 100644 core/plugins/logger/logrus/README.md delete mode 100644 core/plugins/logger/logrus/logrus.go delete mode 100644 core/plugins/logger/logrus/logrus_test.go delete mode 100644 core/plugins/logger/logrus/options.go delete mode 100644 core/plugins/logger/zap/options.go delete mode 100644 core/plugins/logger/zap/zap.go delete mode 100644 core/plugins/logger/zap/zap_test.go delete mode 100644 pkg/config/gormdb/logger/logger.go delete mode 100644 pkg/config/gormdb/logger/logger_test.go diff --git a/core/logger/default.go b/core/logger/default.go deleted file mode 100644 index 05189e9..0000000 --- a/core/logger/default.go +++ /dev/null @@ -1,192 +0,0 @@ -package logger - -import ( - "context" - "fmt" - "log" - "os" - "path/filepath" - "sort" - "strings" - "sync" - - "github.com/mss-boot-io/mss-boot/core/logger/formatter" - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -func init() { - lvl, err := level.GetLevel(os.Getenv("LOG_LEVEL")) - if err != nil { - lvl = level.Info - } - - DefaultLogger = NewHelper(NewLogger(WithLevel(lvl))) -} - -type defaultLogger struct { - sync.RWMutex - opts Options - log *log.Logger -} - -// Init (opts...) should only overwrite provided Options -func (l *defaultLogger) Init(opts ...Option) error { - for _, o := range opts { - o(&l.opts) - } - l.log = log.New(l.opts.Out, "", log.Lshortfile|log.LstdFlags) - //l.log = log.New(os.Stderr, "", log.LstdFlags|log.Llongfile) - return nil -} - -// String string -func (l *defaultLogger) String() string { - return "default" -} - -// Fields Fields -func (l *defaultLogger) Fields(fields map[string]interface{}) Logger { - l.Lock() - l.opts.Fields = copyFields(fields) - l.Unlock() - return l -} - -func copyFields(src map[string]interface{}) map[string]interface{} { - dst := make(map[string]interface{}, len(src)) - for k, v := range src { - dst[k] = v - } - return dst -} - -// logCallerFilePath returns a package/file:line description of the caller, -// preserving only the leaf directory Name and file Name. -func logCallerFilePath(loggingFilePath string) string { - // To make sure we trim the path correctly on Windows too, we - // counter-intuitively need to use '/' and *not* os.PathSeparator here, - // because the path given originates from Go stdlib, specifically - // runtime.Caller() which (as of Mar/17) returns forward slashes even on - // Windows. - // - // See https://github.com/golang/go/issues/3335 - // and https://github.com/golang/go/issues/18151 - // - // for discussion on the issue on Go side. - idx := strings.LastIndexByte(loggingFilePath, filepath.Separator) - if idx == -1 { - return loggingFilePath - } - idx = strings.LastIndexByte(loggingFilePath[:idx], filepath.Separator) - if idx == -1 { - return loggingFilePath - } - return loggingFilePath[idx+1:] -} - -// Log log -func (l *defaultLogger) Log(level level.Level, v ...interface{}) { - l.logf(level, "", v...) -} - -// Logf logf -func (l *defaultLogger) Logf(level level.Level, format string, v ...interface{}) { - l.logf(level, format, v...) -} - -func (l *defaultLogger) logf(level level.Level, format string, v ...interface{}) { - // TODO decide does we need to write message if log Level.Level not used? - if !l.opts.Level.Enabled(level) { - return - } - - l.RLock() - fields := copyFields(l.opts.Fields) - l.RUnlock() - - fields["Level"] = level.String() - - //if _, file, line, ok := runtime.Caller(l.opts.CallerSkipCount); ok { - // fields["file"] = fmt.Sprintf("%s:%d", logCallerFilePath(file), line) - //} - - rec := formatter.Record{ - //Timestamp: time.Now(), - Metadata: make(map[string]string, len(fields)), - } - if format == "" { - rec.Message = fmt.Sprint(v...) - } else { - rec.Message = fmt.Sprintf(format, v...) - } - - keys := make([]string, 0, len(fields)) - for k, v := range fields { - keys = append(keys, k) - rec.Metadata[k] = fmt.Sprintf("%v", v) - } - - sort.Strings(keys) - metadata := "" - - for i, k := range keys { - if i == 0 { - metadata += fmt.Sprintf("%s:%v", k, fields[k]) - } else { - metadata += fmt.Sprintf(" %s:%v", k, fields[k]) - } - } - - var name string - if l.opts.Name != "" { - name = "[" + l.opts.Name + "]" - } - //t := rec.Timestamp.Format("2006-01-02 15:04:05.000Z0700") - //fmt.Printf("%s\n", t) - //fmt.Printf("%s\n", Name) - //fmt.Printf("%s\n", metadata) - //fmt.Printf("%v\n", rec.Message) - logStr := "" - if name == "" { - logStr = fmt.Sprintf("%s %v\n", metadata, rec.Message) - } else { - logStr = fmt.Sprintf("%s %s %v\n", name, metadata, rec.Message) - } - err := l.log.Output(l.opts.CallerSkipCount+1, logStr) - - //_, err := l.opts.Out.Write([]byte(logStr)) - if err != nil { - log.Printf("log [Logf] write error: %s \n", err.Error()) - } - -} - -// Options get Options -func (l *defaultLogger) Options() Options { - // not guard against Options Context values - l.RLock() - opts := l.opts - opts.Fields = copyFields(l.opts.Fields) - l.RUnlock() - return opts -} - -// NewLogger builds a new logger based on Options -func NewLogger(opts ...Option) Logger { - // Default Options - options := Options{ - Level: level.Info, - Fields: make(map[string]interface{}), - Out: os.Stderr, - CallerSkipCount: 3, - Context: context.Background(), - Name: "", - } - - l := &defaultLogger{opts: options} - if err := l.Init(opts...); err != nil { - l.Log(level.Fatal, err) - } - - return l -} diff --git a/core/logger/default_test.go b/core/logger/default_test.go deleted file mode 100644 index a6d0d78..0000000 --- a/core/logger/default_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package logger - -/* - * @Author: lwnmengjing - * @Date: 2023/5/29 07:20:43 - * @Last Modified by: lwnmengjing - * @Last Modified time: 2023/5/29 07:20:43 - */ - -import "testing" - -func Test_logCallerFilePath(t *testing.T) { - type args struct { - loggingFilePath string - } - tests := []struct { - name string - args args - want string - }{ - { - name: "test linux/unix", - args: args{ - loggingFilePath: "/root/project/test.go", - }, - want: "project/test.go", - }, - { - name: "test windows", - args: args{ - loggingFilePath: "C:\\root\\project\\test.go", - }, - want: "project\\test.go", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := logCallerFilePath(tt.args.loggingFilePath); got != tt.want { - t.Errorf("logCallerFilePath() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/core/logger/formatter/formatter.go b/core/logger/formatter/formatter.go deleted file mode 100644 index 0299209..0000000 --- a/core/logger/formatter/formatter.go +++ /dev/null @@ -1,53 +0,0 @@ -package formatter - -import ( - "encoding/json" - "fmt" - "time" -) - -var ( - // DefaultSize Default buffer size if any - DefaultSize = 256 -) - -// Log is debug log interface for reading and writing logs -type Log interface { - // Read reads log entries from the logger - Read(...ReadOption) ([]Record, error) - // Write writes records to log - Write(Record) error - // Stream log records - Stream() (Stream, error) -} - -// Record is log record entry -type Record struct { - // Timestamp of logged event - Timestamp time.Time `json:"timestamp"` - // Metadata to enrich log record - Metadata map[string]string `json:"metadata"` - // Value contains log entry - Message interface{} `json:"message"` -} - -// Stream returns a log stream -type Stream interface { - Chan() <-chan Record - Stop() error -} - -// FormatFunc is a function which formats the output -type FormatFunc func(Record) string - -// TextFormat returns text format -func TextFormat(r Record) string { - t := r.Timestamp.Format("2006-01-02 15:04:05") - return fmt.Sprintf("%s %v ", t, r.Message) -} - -// JSONFormat is a json Format func -func JSONFormat(r Record) string { - b, _ := json.Marshal(r) - return string(b) + " " -} diff --git a/core/logger/formatter/options.go b/core/logger/formatter/options.go deleted file mode 100644 index deef320..0000000 --- a/core/logger/formatter/options.go +++ /dev/null @@ -1,71 +0,0 @@ -package formatter - -import "time" - -// Option used by the logger -type Option func(*Options) - -// Options are logger options -type Options struct { - // Name of the log - Name string - // Size is the size of ring buffer - Size int - // Format specifies the output format - Format FormatFunc -} - -// Name of the log -func Name(n string) Option { - return func(o *Options) { - o.Name = n - } -} - -// Size sets the size of the ring buffer -func Size(s int) Option { - return func(o *Options) { - o.Size = s - } -} - -// Format formant -func Format(f FormatFunc) Option { - return func(o *Options) { - o.Format = f - } -} - -// DefaultOptions returns default options -func DefaultOptions() Options { - return Options{ - Size: DefaultSize, - } -} - -// ReadOptions for querying the logs -type ReadOptions struct { - // Since what time in past to return the logs - Since time.Time - // Count specifies number of logs to return - Count int - // Stream requests continuous log stream - Stream bool -} - -// ReadOption used for reading the logs -type ReadOption func(*ReadOptions) - -// Since sets the time since which to return the log records -func Since(s time.Time) ReadOption { - return func(o *ReadOptions) { - o.Since = s - } -} - -// Count sets the number of log records to return -func Count(c int) ReadOption { - return func(o *ReadOptions) { - o.Count = c - } -} diff --git a/core/logger/helper.go b/core/logger/helper.go deleted file mode 100644 index 9803da5..0000000 --- a/core/logger/helper.go +++ /dev/null @@ -1,133 +0,0 @@ -package logger - -import ( - "os" - - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -// Helper is a logger helper -type Helper struct { - // Logger is the logger - Logger - fields map[string]interface{} -} - -// NewHelper new a logger helper -func NewHelper(log Logger) *Helper { - return &Helper{Logger: log} -} - -// Info info level -func (h *Helper) Info(args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Info) { - return - } - h.Logger.Fields(h.fields).Log(level.Info, args...) -} - -// Infof info level -func (h *Helper) Infof(template string, args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Info) { - return - } - h.Logger.Fields(h.fields).Logf(level.Info, template, args...) -} - -// Trace trace level -func (h *Helper) Trace(args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Trace) { - return - } - h.Logger.Fields(h.fields).Log(level.Trace, args...) -} - -// Tracef trace level -func (h *Helper) Tracef(template string, args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Trace) { - return - } - h.Logger.Fields(h.fields).Logf(level.Trace, template, args...) -} - -// Debug debug level -func (h *Helper) Debug(args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Debug) { - return - } - h.Logger.Fields(h.fields).Log(level.Debug, args...) -} - -// Debugf debug level -func (h *Helper) Debugf(template string, args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Debug) { - return - } - h.Logger.Fields(h.fields).Logf(level.Debug, template, args...) -} - -// Warn warn level -func (h *Helper) Warn(args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Warn) { - return - } - h.Logger.Fields(h.fields).Log(level.Warn, args...) -} - -// Warnf warn level -func (h *Helper) Warnf(template string, args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Warn) { - return - } - h.Logger.Fields(h.fields).Logf(level.Warn, template, args...) -} - -// Error error level -func (h *Helper) Error(args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Error) { - return - } - h.Logger.Fields(h.fields).Log(level.Error, args...) -} - -// Errorf error level -func (h *Helper) Errorf(template string, args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Error) { - return - } - h.Logger.Fields(h.fields).Logf(level.Error, template, args...) -} - -// Fatal fatal level -func (h *Helper) Fatal(args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Fatal) { - return - } - h.Logger.Fields(h.fields).Log(level.Fatal, args...) - os.Exit(1) -} - -// Fatalf fatal level -func (h *Helper) Fatalf(template string, args ...interface{}) { - if !h.Logger.Options().Level.Enabled(level.Fatal) { - return - } - h.Logger.Fields(h.fields).Logf(level.Fatal, template, args...) - os.Exit(1) -} - -// WithError with error -func (h *Helper) WithError(err error) *Helper { - fields := copyFields(h.fields) - fields["error"] = err - return &Helper{Logger: h.Logger, fields: fields} -} - -// WithFields with fields -func (h *Helper) WithFields(fields map[string]interface{}) *Helper { - nfields := copyFields(fields) - for k, v := range h.fields { - nfields[k] = v - } - return &Helper{Logger: h.Logger, fields: nfields} -} diff --git a/core/logger/level/level.go b/core/logger/level/level.go deleted file mode 100644 index 9ef0d3b..0000000 --- a/core/logger/level/level.go +++ /dev/null @@ -1,73 +0,0 @@ -package level - -/* - * @Author: lwnmengjing - * @Date: 2021/6/15 5:58 下午 - * @Last Modified by: lwnmengjing - * @Last Modified time: 2021/6/15 5:58 下午 - */ - -import ( - "fmt" - "strings" -) - -//go:generate stringer -type level -output level_string.go - -// Level level for logger -type Level int8 - -const ( - // Trace level. Designates finer-grained informational events than the Debug. - Trace Level = iota - 2 - // Debug level. Usually only enabled when debugging. Very verbose logging. - Debug - // Info is the default logging priority. - // General operational entries about what's going on inside the application. - Info - // Warn level. Non-critical entries that deserve eyes. - Warn - // Error level. Logs. Used for errors that should definitely be noted. - Error - // Fatal level. Logs and then calls `logger.Exit(1)`. highest level of severity. - Fatal -) - -// ToGorm trans to gorm log level -func (l Level) ToGorm() int { - switch l { - case Fatal, Error: - return 2 - case Warn: - return 3 - case Info, Debug, Trace: - return 4 - default: - return 1 - } -} - -// Enabled returns true if the given level is at or above this level. -func (l Level) Enabled(lvl Level) bool { - return lvl >= l -} - -// GetLevel converts a level string into a logger Level value. -// returns an error if the input string does not match known values. -func GetLevel(levelStr string) (Level, error) { - switch strings.ToLower(levelStr) { - case strings.ToLower(Trace.String()): - return Trace, nil - case strings.ToLower(Debug.String()): - return Debug, nil - case strings.ToLower(Info.String()): - return Info, nil - case strings.ToLower(Warn.String()): - return Warn, nil - case strings.ToLower(Error.String()): - return Error, nil - case strings.ToLower(Fatal.String()): - return Fatal, nil - } - return Info, fmt.Errorf("unknown level String: '%s', defaulting to InfoLevel", levelStr) -} diff --git a/core/logger/level/level_string.go b/core/logger/level/level_string.go deleted file mode 100644 index 7eeb1ff..0000000 --- a/core/logger/level/level_string.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by "stringer -type level -output level_string.go"; DO NOT EDIT. - -package level - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[Trace - -2] - _ = x[Debug - -1] - _ = x[Info-0] - _ = x[Warn-1] - _ = x[Error-2] - _ = x[Fatal-3] -} - -const _Level_name = "TraceDebugInfoWarnErrorFatal" - -var _Level_index = [...]uint8{0, 5, 10, 14, 18, 23, 28} - -func (i Level) String() string { - i -= -2 - if i < 0 || i >= Level(len(_Level_index)-1) { - return "level(" + strconv.FormatInt(int64(i+-2), 10) + ")" - } - return _Level_name[_Level_index[i]:_Level_index[i+1]] -} diff --git a/core/logger/logger.go b/core/logger/logger.go deleted file mode 100644 index 220b486..0000000 --- a/core/logger/logger.go +++ /dev/null @@ -1,119 +0,0 @@ -package logger - -import ( - "os" - - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -var ( - // DefaultLogger logger - DefaultLogger Logger -) - -// Logger is a generic logging interface -type Logger interface { - // Init initialises Options - Init(options ...Option) error - // Options The Logger Options - Options() Options - // Fields set Fields to always be logged - Fields(fields map[string]interface{}) Logger - // Log writes a log entry - Log(level level.Level, v ...interface{}) - // Logf writes a formatted log entry - Logf(level level.Level, format string, v ...interface{}) - // String returns the Name of logger - String() string -} - -// Init init default logger -func Init(opts ...Option) error { - return DefaultLogger.Init(opts...) -} - -// Info Log writes a log entry -func Info(args ...interface{}) { - DefaultLogger.Log(level.Info, args...) -} - -// Infof Log writes a log entry -func Infof(template string, args ...interface{}) { - DefaultLogger.Logf(level.Info, template, args...) -} - -// Trace Log writes a log entry -func Trace(args ...interface{}) { - DefaultLogger.Log(level.Trace, args...) -} - -// Tracef Log writes a log entry -func Tracef(template string, args ...interface{}) { - DefaultLogger.Logf(level.Trace, template, args...) -} - -// Debug Log writes a log entry -func Debug(args ...interface{}) { - DefaultLogger.Log(level.Debug, args...) -} - -// Debugf Log writes a log entry -func Debugf(template string, args ...interface{}) { - DefaultLogger.Logf(level.Debug, template, args...) -} - -// Warn Log writes a log entry -func Warn(args ...interface{}) { - DefaultLogger.Log(level.Warn, args...) -} - -// Warnf Log writes a log entry -func Warnf(template string, args ...interface{}) { - DefaultLogger.Logf(level.Warn, template, args...) -} - -// Error Log writes a log entry -func Error(args ...interface{}) { - DefaultLogger.Log(level.Error, args...) -} - -// Errorf Log writes a log entry -func Errorf(template string, args ...interface{}) { - DefaultLogger.Logf(level.Error, template, args...) -} - -// Fatal Log writes a log entry -func Fatal(args ...interface{}) { - DefaultLogger.Log(level.Fatal, args...) - os.Exit(1) -} - -// Fatalf Log writes a log entry -func Fatalf(template string, args ...interface{}) { - DefaultLogger.Logf(level.Fatal, template, args...) - os.Exit(1) -} - -// Log writes a log entry -func Log(l level.Level, v ...interface{}) { - DefaultLogger.Log(l, v...) -} - -// Logf writes a log entry -func Logf(l level.Level, format string, v ...interface{}) { - DefaultLogger.Logf(l, format, v...) -} - -// V Returns true if the given Level is at or lower the current logger Level -func V(lvl level.Level, log Logger) bool { - l := DefaultLogger - if log != nil { - l = log - } - return l.Options().Level <= lvl -} - -// Level return logger Level -func Level() level.Level { - return DefaultLogger.Options().Level -} diff --git a/core/logger/options.go b/core/logger/options.go deleted file mode 100644 index ad500ef..0000000 --- a/core/logger/options.go +++ /dev/null @@ -1,72 +0,0 @@ -package logger - -import ( - "context" - "io" - - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -// Option set Options -type Option func(*Options) - -// Options options -type Options struct { - // The logging Level the logger should log at. default is `InfoLevel` - Level level.Level - // Fields to always be logged - Fields map[string]interface{} - // It's common to set this to a file, or leave it default which is `os.Stderr` - Out io.Writer - // Caller skip frame count for file:line info - CallerSkipCount int - // Alternative Options - Context context.Context - // Name logger Name - Name string -} - -// WithFields set default Fields for the logger -func WithFields(fields map[string]interface{}) Option { - return func(args *Options) { - args.Fields = fields - } -} - -// WithLevel set default Level for the logger -func WithLevel(level level.Level) Option { - return func(args *Options) { - args.Level = level - } -} - -// WithOutput set default output writer for the logger -func WithOutput(out io.Writer) Option { - return func(args *Options) { - args.Out = out - } -} - -// WithCallerSkipCount set frame count to skip -func WithCallerSkipCount(c int) Option { - return func(args *Options) { - args.CallerSkipCount = c - } -} - -// WithName set Name for logger -func WithName(name string) Option { - return func(args *Options) { - args.Name = name - } -} - -// SetOption set option -func SetOption(k, v interface{}) Option { - return func(o *Options) { - if o.Context == nil { - o.Context = context.Background() - } - o.Context = context.WithValue(o.Context, k, v) - } -} diff --git a/core/plugins/logger/logrus/README.md b/core/plugins/logger/logrus/README.md deleted file mode 100644 index 91e2a87..0000000 --- a/core/plugins/logger/logrus/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# logrus - -[logrus](https://github.com/sirupsen/logrus) logger implementation for __go-admin__ [meta logger](https://github.com/mss-boot-io/mss-boot/core/tree/master/logger). - -## Usage - -```go -import ( - "os" - "github.com/sirupsen/logrus" - "github.com/mss-boot-io/mss-boot/core/logger" -) - -func ExampleWithOutput() { - logger.DefaultLogger = NewLogger(logger.WithOutput(os.Stdout)) - logger.Infof("testing: %s", "Infof") -} - -func ExampleWithLogger() { - l := logrus.New() // *logrus.Logger - logger.DefaultLogger = NewLogger(WithLogger(l)) - logger.Infof("testing: %s", "Infof") -} -``` - diff --git a/core/plugins/logger/logrus/logrus.go b/core/plugins/logger/logrus/logrus.go deleted file mode 100644 index a7d32c4..0000000 --- a/core/plugins/logger/logrus/logrus.go +++ /dev/null @@ -1,169 +0,0 @@ -package logrus - -import ( - "context" - "fmt" - "os" - - "github.com/sirupsen/logrus" - - "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -type entryLogger interface { - WithFields(fields logrus.Fields) *logrus.Entry - WithError(err error) *logrus.Entry - - Log(level logrus.Level, args ...interface{}) - Logf(level logrus.Level, format string, args ...interface{}) -} - -type logrusLogger struct { - Logger entryLogger - opts Options -} - -func (l *logrusLogger) Init(opts ...logger.Option) error { - for _, o := range opts { - o(&l.opts.Options) - } - - if formatter, ok := l.opts.Context.Value(formatterKey{}).(logrus.Formatter); ok { - skip, _ := l.opts.Context.Value(skipKey{}).(int) - if skip == 0 { - skip = 10 - } - - switch f := formatter.(type) { - case *logrus.JSONFormatter: - f.CallerPrettyfier = callerPrettyfier(skip) - case *logrus.TextFormatter: - f.CallerPrettyfier = callerPrettyfier(skip) - } - l.opts.Formatter = formatter - } - if hs, ok := l.opts.Context.Value(hooksKey{}).(logrus.LevelHooks); ok { - l.opts.Hooks = hs - } - if caller, ok := l.opts.Context.Value(reportCallerKey{}).(bool); ok && caller { - l.opts.ReportCaller = caller - } - if exitFunction, ok := l.opts.Context.Value(exitKey{}).(func(int)); ok { - l.opts.ExitFunc = exitFunction - } - - switch ll := l.opts.Context.Value(logrusLoggerKey{}).(type) { - case *logrus.Logger: - // overwrite default options - l.opts.Level = logrusToLoggerLevel(ll.GetLevel()) - l.opts.Out = ll.Out - l.opts.Formatter = ll.Formatter - l.opts.Hooks = ll.Hooks - l.opts.ReportCaller = ll.ReportCaller - l.opts.ExitFunc = ll.ExitFunc - l.Logger = ll - case *logrus.Entry: - // overwrite default options - el := ll.Logger - l.opts.Level = logrusToLoggerLevel(el.GetLevel()) - l.opts.Out = el.Out - l.opts.Formatter = el.Formatter - l.opts.Hooks = el.Hooks - l.opts.ReportCaller = el.ReportCaller - l.opts.ExitFunc = el.ExitFunc - l.Logger = ll - case nil: - log := logrus.New() // defaults - log.SetLevel(loggerToLogrusLevel(l.opts.Level)) - log.SetOutput(l.opts.Out) - log.SetFormatter(l.opts.Formatter) - log.ReplaceHooks(l.opts.Hooks) - log.SetReportCaller(l.opts.ReportCaller) - log.ExitFunc = l.opts.ExitFunc - l.Logger = log - default: - return fmt.Errorf("invalid logrus type: %T", ll) - } - - return nil -} - -func (l *logrusLogger) String() string { - return "logrus" -} - -func (l *logrusLogger) Fields(fields map[string]interface{}) logger.Logger { - return &logrusLogger{l.Logger.WithFields(fields), l.opts} -} - -func (l *logrusLogger) Log(lvl level.Level, args ...interface{}) { - l.Logger.Log(loggerToLogrusLevel(lvl), args...) -} - -func (l *logrusLogger) Logf(lvl level.Level, format string, args ...interface{}) { - l.Logger.Logf(loggerToLogrusLevel(lvl), format, args...) -} - -// Options options -func (l *logrusLogger) Options() logger.Options { - return l.opts.Options -} - -// NewLogger New builds a new logger based on options -func NewLogger(opts ...logger.Option) logger.Logger { - // Default options - options := Options{ - Options: logger.Options{ - Level: level.Info, - Fields: make(map[string]interface{}), - Out: os.Stderr, - Context: context.Background(), - }, - Formatter: &logrus.TextFormatter{CallerPrettyfier: callerPrettyfier(11)}, - Hooks: make(logrus.LevelHooks), - ReportCaller: false, - ExitFunc: os.Exit, - } - l := &logrusLogger{opts: options} - _ = l.Init(opts...) - return l -} - -func loggerToLogrusLevel(l level.Level) logrus.Level { - switch l { - case level.Trace: - return logrus.TraceLevel - case level.Debug: - return logrus.DebugLevel - case level.Info: - return logrus.InfoLevel - case level.Warn: - return logrus.WarnLevel - case level.Error: - return logrus.ErrorLevel - case level.Fatal: - return logrus.FatalLevel - default: - return logrus.InfoLevel - } -} - -func logrusToLoggerLevel(l logrus.Level) level.Level { - switch l { - case logrus.TraceLevel: - return level.Trace - case logrus.DebugLevel: - return level.Debug - case logrus.InfoLevel: - return level.Info - case logrus.WarnLevel: - return level.Warn - case logrus.ErrorLevel: - return level.Error - case logrus.FatalLevel: - return level.Fatal - default: - return level.Info - } -} diff --git a/core/plugins/logger/logrus/logrus_test.go b/core/plugins/logger/logrus/logrus_test.go deleted file mode 100644 index bb39f8e..0000000 --- a/core/plugins/logger/logrus/logrus_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package logrus - -import ( - "errors" - "os" - "testing" - - "github.com/sirupsen/logrus" - - "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -func TestName(t *testing.T) { - l := NewLogger() - - if l.String() != "logrus" { - t.Errorf("error: name expected 'logrus' actual: %s", l.String()) - } - - t.Logf("testing logger name: %s", l.String()) -} - -func TestWithFields(t *testing.T) { - l := NewLogger(logger.WithOutput(os.Stdout)).Fields(map[string]interface{}{ - "k1": "v1", - "k2": 123456, - }) - - logger.DefaultLogger = l - - logger.Log(level.Info, "testing: Info") - logger.Logf(level.Info, "testing: %s", "Infof") -} - -func TestWithError(t *testing.T) { - l := NewLogger().Fields(map[string]interface{}{"error": errors.New("boom!")}) - logger.DefaultLogger = l - - logger.Log(level.Info, "testing: error") -} - -func TestWithLogger(t *testing.T) { - // with *logrus.Log - l := NewLogger(WithLogger(logrus.StandardLogger())).Fields(map[string]interface{}{ - "k1": "v1", - "k2": 123456, - }) - logger.DefaultLogger = l - logger.Log(level.Info, "testing: with *logrus.Log") - - // with *logrus.Entry - el := NewLogger(WithLogger(logrus.NewEntry(logrus.StandardLogger()))).Fields(map[string]interface{}{ - "k3": 3.456, - "k4": true, - }) - logger.DefaultLogger = el - logger.Log(level.Info, "testing: with *logrus.Entry") -} - -func TestJSON(t *testing.T) { - logger.DefaultLogger = NewLogger(WithJSONFormatter(&logrus.JSONFormatter{})) - - logger.Logf(level.Info, "test logf: %s", "name") -} - -func TestSetLevel(t *testing.T) { - logger.DefaultLogger = NewLogger() - - logger.Init(logger.WithLevel(level.Debug)) - logger.Logf(level.Debug, "test show debug: %s", "debug msg") - - logger.Init(logger.WithLevel(level.Info)) - logger.Logf(level.Debug, "test non-show debug: %s", "debug msg") -} - -func TestWithReportCaller(t *testing.T) { - logger.DefaultLogger = NewLogger(ReportCaller(), WithJSONFormatter(&logrus.JSONFormatter{})) - - logger.Infof("testing: %s", "WithReportCaller") - logger.Logf(level.Info, "testing: %s", "WithReportCaller") -} diff --git a/core/plugins/logger/logrus/options.go b/core/plugins/logger/logrus/options.go deleted file mode 100644 index 3b197d2..0000000 --- a/core/plugins/logger/logrus/options.go +++ /dev/null @@ -1,83 +0,0 @@ -package logrus - -import ( - "runtime" - "strconv" - - "github.com/sirupsen/logrus" - - "github.com/mss-boot-io/mss-boot/core/logger" -) - -// Options Options -type Options struct { - logger.Options - Formatter logrus.Formatter - Hooks logrus.LevelHooks - // Flag for whether to log caller info (off by default) - ReportCaller bool - // Exit Function to call when FatalLevel log - ExitFunc func(int) - CallerSkipCount int -} - -type formatterKey struct{} - -// WithTextTextFormatter withTextTextFormatter -func WithTextTextFormatter(formatter *logrus.TextFormatter) logger.Option { - return logger.SetOption(formatterKey{}, formatter) -} - -// WithJSONFormatter withJSONFormatter -func WithJSONFormatter(formatter *logrus.JSONFormatter) logger.Option { - return logger.SetOption(formatterKey{}, formatter) -} - -type hooksKey struct{} - -// WithLevelHooks withLevelHooks -func WithLevelHooks(hooks logrus.LevelHooks) logger.Option { - return logger.SetOption(hooksKey{}, hooks) -} - -type reportCallerKey struct{} - -// ReportCaller warning to use this option. because logrus doest not open CallerDepth option -// this will only print this package -func ReportCaller() logger.Option { - return logger.SetOption(reportCallerKey{}, true) -} - -type exitKey struct{} - -// WithExitFunc withExitFunc -func WithExitFunc(exit func(int)) logger.Option { - return logger.SetOption(exitKey{}, exit) -} - -type logrusLoggerKey struct{} - -// WithLogger withLogger -func WithLogger(l logrus.StdLogger) logger.Option { - return logger.SetOption(logrusLoggerKey{}, l) -} - -type skipKey struct{} - -// WithSkip set skip -func WithSkip(skip int) logger.Option { - return logger.SetOption(skipKey{}, skip) -} - -func callerPrettyfier(skip int) func(f *runtime.Frame) (string, string) { - return func(f *runtime.Frame) (string, string) { - pc := make([]uintptr, 25) - runtime.Callers(skip, pc) - frames := runtime.CallersFrames(pc) - f1, _ := frames.Next() - f = &f1 - funcName := f.Func.Name() - fileName := f.File + ":" + strconv.Itoa(f.Line) - return funcName, fileName - } -} diff --git a/core/plugins/logger/zap/options.go b/core/plugins/logger/zap/options.go deleted file mode 100644 index 930dee4..0000000 --- a/core/plugins/logger/zap/options.go +++ /dev/null @@ -1,57 +0,0 @@ -package zap - -import ( - "io" - - "go.uber.org/zap" - "go.uber.org/zap/zapcore" - - "github.com/mss-boot-io/mss-boot/core/logger" -) - -// Options is zap logger options -type Options struct { - logger.Options -} - -type callerSkipKey struct{} - -// WithCallerSkip pass caller skip to logger -func WithCallerSkip(i int) logger.Option { - return logger.SetOption(callerSkipKey{}, i) -} - -type configKey struct{} - -// WithConfig pass zap.Config to logger -func WithConfig(c zap.Config) logger.Option { - return logger.SetOption(configKey{}, c) -} - -type encoderConfigKey struct{} - -// WithEncoderConfig pass zapcore.EncoderConfig to logger -func WithEncoderConfig(c zapcore.EncoderConfig) logger.Option { - return logger.SetOption(encoderConfigKey{}, c) -} - -type encoderKey struct{} - -// WithEncoder pass zapcore.Encoder to logger -func WithEncoder(e zapcore.Encoder) logger.Option { - return logger.SetOption(encoderKey{}, e) -} - -type namespaceKey struct{} - -// WithNamespace set namespace -func WithNamespace(namespace string) logger.Option { - return logger.SetOption(namespaceKey{}, namespace) -} - -type writerKey struct{} - -// WithOutput set output -func WithOutput(out io.Writer) logger.Option { - return logger.SetOption(writerKey{}, out) -} diff --git a/core/plugins/logger/zap/zap.go b/core/plugins/logger/zap/zap.go deleted file mode 100644 index 67b5cf3..0000000 --- a/core/plugins/logger/zap/zap.go +++ /dev/null @@ -1,237 +0,0 @@ -package zap - -import ( - "context" - "fmt" - "io" - "os" - "sync" - - "go.uber.org/zap" - "go.uber.org/zap/zapcore" - - "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" -) - -type zaplog struct { - cfg zap.Config - zap *zap.Logger - opts logger.Options - sync.RWMutex - fields map[string]interface{} -} - -func (l *zaplog) Init(opts ...logger.Option) error { - //var err error - - for _, o := range opts { - o(&l.opts) - } - - zapConfig := zap.NewProductionConfig() - if zconfig, ok := l.opts.Context.Value(configKey{}).(zap.Config); ok { - zapConfig = zconfig - } - - if zcconfig, ok := l.opts.Context.Value(encoderConfigKey{}).(zapcore.EncoderConfig); ok { - zapConfig.EncoderConfig = zcconfig - } - - writer, ok := l.opts.Context.Value(writerKey{}).(io.Writer) - if !ok { - writer = os.Stdout - } - - skip, ok := l.opts.Context.Value(callerSkipKey{}).(int) - if !ok || skip < 1 { - skip = 1 - } - - encoder, ok := l.opts.Context.Value(encoderKey{}).(zapcore.Encoder) - if !ok { - encoder = zapcore.NewConsoleEncoder(zapConfig.EncoderConfig) - } - - // Set log Level if not default - zapConfig.Level = zap.NewAtomicLevel() - if l.opts.Level != level.Info { - zapConfig.Level.SetLevel(loggerToZapLevel(l.opts.Level)) - } - zapConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - - logCore := zapcore.NewCore( - encoder, - zapcore.NewMultiWriteSyncer(zapcore.AddSync(writer)), - zapConfig.Level) - - log := zap.New(logCore, - zap.AddCaller(), - zap.AddCallerSkip(skip), - zap.AddStacktrace(zap.DPanicLevel)) - //log, err := zapConfig.Build(zap.AddCallerSkip(skip)) - //if err != nil { - // return err - //} - - // Adding seed fields if exist - if l.opts.Fields != nil { - data := []zap.Field{} - for k, v := range l.opts.Fields { - data = append(data, zap.Any(k, v)) - } - log = log.With(data...) - } - - // Adding namespace - if namespace, ok := l.opts.Context.Value(namespaceKey{}).(string); ok { - log = log.With(zap.Namespace(namespace)) - } - - // defer log.Sync() ?? - - l.cfg = zapConfig - l.zap = log - l.fields = make(map[string]interface{}) - - return nil -} - -func (l *zaplog) Fields(fields map[string]interface{}) logger.Logger { - l.Lock() - nfields := make(map[string]interface{}, len(l.fields)) - for k, v := range l.fields { - nfields[k] = v - } - l.Unlock() - for k, v := range fields { - nfields[k] = v - } - - data := make([]zap.Field, 0, len(nfields)) - for k, v := range fields { - data = append(data, zap.Any(k, v)) - } - - zl := &zaplog{ - cfg: l.cfg, - zap: l.zap, - opts: l.opts, - fields: nfields, - } - - return zl -} - -func (l *zaplog) Error(err error) logger.Logger { - return l.Fields(map[string]interface{}{"error": err}) -} - -func (l *zaplog) Log(level level.Level, args ...interface{}) { - l.RLock() - data := make([]zap.Field, 0, len(l.fields)) - for k, v := range l.fields { - data = append(data, zap.Any(k, v)) - } - l.RUnlock() - - lvl := loggerToZapLevel(level) - msg := fmt.Sprint(args...) - switch lvl { - case zap.DebugLevel: - l.zap.Debug(msg, data...) - case zap.InfoLevel: - l.zap.Info(msg, data...) - case zap.WarnLevel: - l.zap.Warn(msg, data...) - case zap.ErrorLevel: - l.zap.Error(msg, data...) - case zap.FatalLevel: - l.zap.Fatal(msg, data...) - } -} - -func (l *zaplog) Logf(level level.Level, format string, args ...interface{}) { - l.RLock() - data := make([]zap.Field, 0, len(l.fields)) - for k, v := range l.fields { - data = append(data, zap.Any(k, v)) - } - l.RUnlock() - - lvl := loggerToZapLevel(level) - msg := fmt.Sprintf(format, args...) - switch lvl { - case zap.DebugLevel: - l.zap.Debug(msg, data...) - case zap.InfoLevel: - l.zap.Info(msg, data...) - case zap.WarnLevel: - l.zap.Warn(msg, data...) - case zap.ErrorLevel: - l.zap.Error(msg, data...) - case zap.FatalLevel: - l.zap.Fatal(msg, data...) - } -} - -func (l *zaplog) String() string { - return "zap" -} - -func (l *zaplog) Options() logger.Options { - return l.opts -} - -// NewLogger New builds a new logger based on options -func NewLogger(opts ...logger.Option) (logger.Logger, error) { - // Default options - options := logger.Options{ - Level: level.Info, - Fields: make(map[string]interface{}), - Out: os.Stderr, - Context: context.Background(), - } - - l := &zaplog{opts: options} - if err := l.Init(opts...); err != nil { - return nil, err - } - - return l, nil -} - -func loggerToZapLevel(l level.Level) zapcore.Level { - switch l { - case level.Trace, level.Debug: - return zap.DebugLevel - case level.Info: - return zap.InfoLevel - case level.Warn: - return zap.WarnLevel - case level.Error: - return zap.ErrorLevel - case level.Fatal: - return zap.FatalLevel - default: - return zap.InfoLevel - } -} - -// zapToLoggerLevel converts zap level to logger level -func zapToLoggerLevel(l zapcore.Level) level.Level { - switch l { - case zap.DebugLevel: - return level.Debug - case zap.InfoLevel: - return level.Info - case zap.WarnLevel: - return level.Warn - case zap.ErrorLevel: - return level.Error - case zap.FatalLevel: - return level.Fatal - default: - return level.Info - } -} diff --git a/core/plugins/logger/zap/zap_test.go b/core/plugins/logger/zap/zap_test.go deleted file mode 100644 index a7d0634..0000000 --- a/core/plugins/logger/zap/zap_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package zap - -import ( - "fmt" - "testing" - - "go.uber.org/zap/zapcore" - - "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" - "github.com/mss-boot-io/mss-boot/core/logger/writer" -) - -func TestName(t *testing.T) { - l, err := NewLogger() - if err != nil { - t.Fatal(err) - } - - if l.String() != "zap" { - t.Errorf("name is error %s", l.String()) - } - - t.Logf("test logger name: %s", l.String()) -} - -func TestLogf(t *testing.T) { - l, err := NewLogger() - if err != nil { - t.Fatal(err) - } - - logger.DefaultLogger = l - logger.Logf(level.Info, "test logf: %s", "name") -} - -func TestSetLevel(t *testing.T) { - l, err := NewLogger() - if err != nil { - t.Fatal(err) - } - logger.DefaultLogger = l - - logger.Init(logger.WithLevel(level.Debug)) - l.Logf(level.Debug, "test show debug: %s", "debug msg") - - logger.Init(logger.WithLevel(level.Info)) - l.Logf(level.Debug, "test non-show debug: %s", "debug msg") -} - -func TestWithReportCaller(t *testing.T) { - var err error - logger.DefaultLogger, err = NewLogger(WithCallerSkip(2)) - if err != nil { - t.Fatal(err) - } - - logger.Logf(level.Info, "testing: %s", "WithReportCaller") -} - -func TestFields(t *testing.T) { - l, err := NewLogger() - if err != nil { - t.Fatal(err) - } - logger.DefaultLogger = l.Fields(map[string]interface{}{ - "x-request-id": "123456abc", - }) - logger.DefaultLogger.Log(level.Info, "hello") -} - -func TestFile(t *testing.T) { - output, err := writer.NewFileWriter( - writer.WithPath("testdata"), - writer.WithSuffix("log"), - ) - if err != nil { - t.Errorf("logger setup error: %s", err.Error()) - } - //var err error - logger.DefaultLogger, err = NewLogger(logger.WithLevel(level.Trace), WithOutput(output)) - if err != nil { - t.Errorf("logger setup error: %s", err.Error()) - } - logger.DefaultLogger = logger.DefaultLogger.Fields(map[string]interface{}{ - "x-request-id": "123456abc", - }) - fmt.Println(logger.DefaultLogger) - logger.DefaultLogger.Log(level.Info, "hello") -} - -func Test_zapToLoggerLevel(t *testing.T) { - type args struct { - l zapcore.Level - } - tests := []struct { - name string - args args - want level.Level - }{ - { - name: "test zapToLoggerLevel", - args: args{ - l: zapcore.DebugLevel, - }, - want: level.Debug, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := zapToLoggerLevel(tt.args.l); got != tt.want { - t.Errorf("zapToLoggerLevel() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/config/gormdb/logger/logger.go b/pkg/config/gormdb/logger/logger.go deleted file mode 100644 index 2d96e54..0000000 --- a/pkg/config/gormdb/logger/logger.go +++ /dev/null @@ -1,171 +0,0 @@ -package logger - -import ( - "context" - "fmt" - "time" - - loggerCore "github.com/mss-boot-io/mss-boot/core/logger" - "github.com/mss-boot-io/mss-boot/core/logger/level" - "gorm.io/gorm/logger" - "gorm.io/gorm/utils" -) - -var log loggerCore.Logger - -func init() { - log = loggerCore.NewLogger() -} - -// Colors -const ( - Reset = "\033[0m" - Red = "\033[31m" - Green = "\033[32m" - Yellow = "\033[33m" - Blue = "\033[34m" - Magenta = "\033[35m" - Cyan = "\033[36m" - White = "\033[37m" - BlueBold = "\033[34;1m" - MagentaBold = "\033[35;1m" - RedBold = "\033[31;1m" - YellowBold = "\033[33;1m" -) - -type gormLogger struct { - logger.Config - infoStr, warnStr, errStr string - traceStr, traceErrStr, traceWarnStr string -} - -func (l *gormLogger) getLogger(ctx context.Context) loggerCore.Logger { - requestID := ctx.Value("X-Request-ID") - if requestID != nil { - return log.Fields(map[string]interface{}{ - "x-request-id": requestID, - }) - } - return log -} - -// LogMode log mode -func (l *gormLogger) LogMode(level logger.LogLevel) logger.Interface { - newLogger := *l - newLogger.LogLevel = level - return &newLogger -} - -// Info print info -func (l gormLogger) Info(ctx context.Context, msg string, data ...interface{}) { - if l.LogLevel >= logger.Info { - //l.Printf(l.infoStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) - log := l.getLogger(ctx) - log.Logf(level.Info, l.infoStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) - } -} - -// Warn print warn messages -func (l gormLogger) Warn(ctx context.Context, msg string, data ...interface{}) { - if l.LogLevel >= logger.Warn { - //l.Printf(l.warnStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) - log := l.getLogger(ctx) - log.Logf(level.Warn, l.warnStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) - } -} - -// Error print error messages -func (l gormLogger) Error(ctx context.Context, msg string, data ...interface{}) { - if l.LogLevel >= logger.Error { - //l.Printf(l.errStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) - log := l.getLogger(ctx) - log.Logf(level.Error, l.errStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) - } -} - -// Trace print sql message -func (l gormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { - if l.LogLevel > logger.Silent { - log := l.getLogger(ctx) - elapsed := time.Since(begin) - switch { - case err != nil && l.LogLevel >= logger.Error: - sql, rows := fc() - if rows == -1 { - //l.Printf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) - log.Logf(level.Trace, l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) - } else { - //l.Printf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) - log.Logf(level.Trace, l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) - } - case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn: - sql, rows := fc() - slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold) - if rows == -1 { - //l.Printf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) - log.Logf(level.Trace, l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) - } else { - //l.Printf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) - log.Logf(level.Trace, l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) - } - case l.LogLevel == logger.Info: - sql, rows := fc() - if rows == -1 { - //l.Printf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) - log.Logf(level.Trace, l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) - } else { - //l.Printf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) - log.Logf(level.Trace, l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) - } - } - } -} - -type traceRecorder struct { - logger.Interface - BeginAt time.Time - SQL string - RowsAffected int64 - Err error -} - -func (l traceRecorder) New() *traceRecorder { - return &traceRecorder{Interface: l.Interface, BeginAt: time.Now()} -} - -func (l *traceRecorder) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { - l.BeginAt = begin - l.SQL, l.RowsAffected = fc() - l.Err = err -} - -// New new a logger -func New(config logger.Config) logger.Interface { - var ( - infoStr = "%s\n[info] " - warnStr = "%s\n[warn] " - errStr = "%s\n[error] " - traceStr = "%s [%.3fms] [rows:%v] %s" - traceWarnStr = "%s %s [%.3fms] [rows:%v] %s" - traceErrStr = "%s %s [%.3fms] [rows:%v] %s" - ) - - if config.Colorful { - infoStr = Green + "%s " + Reset + Green + "[info] " + Reset - warnStr = BlueBold + "%s " + Reset + Magenta + "[warn] " + Reset - errStr = Magenta + "%s " + Reset + Red + "[error] " + Reset - traceStr = Green + "%s " + Reset + Yellow + "[%.3fms] " + BlueBold + "[rows:%v]" + Reset + " %s" - traceWarnStr = Green + "%s " + Yellow + "%s " + Reset + RedBold + "[%.3fms] " + Yellow + "[rows:%v]" + Magenta + " %s" + Reset - traceErrStr = RedBold + "%s " + MagentaBold + "%s " + Reset + Yellow + "[%.3fms] " + BlueBold + "[rows:%v]" + Reset + " %s" - } - - return &gormLogger{ - Config: config, - infoStr: infoStr, - warnStr: warnStr, - errStr: errStr, - traceStr: traceStr, - traceWarnStr: traceWarnStr, - traceErrStr: traceErrStr, - } -} diff --git a/pkg/config/gormdb/logger/logger_test.go b/pkg/config/gormdb/logger/logger_test.go deleted file mode 100644 index 8424f63..0000000 --- a/pkg/config/gormdb/logger/logger_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package logger - -import ( - "context" - "testing" - "time" - - loggerCore "github.com/mss-boot-io/mss-boot/core/logger" - "gorm.io/gorm/logger" -) - -func TestNew(t *testing.T) { - l := New(logger.Config{ - SlowThreshold: time.Second, - Colorful: true, - LogLevel: logger.LogLevel( - loggerCore.DefaultLogger.Options().Level.ToGorm()), - }) - l.Info(context.TODO(), "test") -} diff --git a/pkg/config/tls.go b/pkg/config/tls.go index 489be4c..db548ae 100644 --- a/pkg/config/tls.go +++ b/pkg/config/tls.go @@ -10,9 +10,8 @@ package config import ( "crypto/tls" "crypto/x509" + "log/slog" "os" - - log "github.com/mss-boot-io/mss-boot/core/logger" ) // TLS config @@ -31,19 +30,19 @@ func (c *TLS) GetTLS() (*tls.Config, error) { // 从证书相关文件中读取和解析信息,得到证书公钥、密钥对 cert, err := tls.LoadX509KeyPair(c.Cert, c.Key) if err != nil { - log.Errorf("tls.LoadX509KeyPair err: %v\n", err) + slog.Error("tls.LoadX509KeyPair error", "err", err) return nil, err } // 创建一个新的、空的 CertPool,并尝试解析 PEM 编码的证书,解析成功会将其加到 CertPool 中 certPool := x509.NewCertPool() ca, err := os.ReadFile(c.Ca) if err != nil { - log.Errorf("ioutil.ReadFile err: %v\n", err) + slog.Error("ioutil.ReadFile error", "err", err) return nil, err } if ok := certPool.AppendCertsFromPEM(ca); !ok { - log.Errorf("certPool.AppendCertsFromPEM err: %v\n", err) + slog.Error("certPool.AppendCertsFromPEM error", "err", err) return nil, err } return &tls.Config{ diff --git a/pkg/response/actions/virtual/search.go b/pkg/response/actions/virtual/search.go index c6b12fb..18ff940 100644 --- a/pkg/response/actions/virtual/search.go +++ b/pkg/response/actions/virtual/search.go @@ -51,8 +51,7 @@ func (e *Search) Handler() gin.HandlerFunc { var count int64 if err := gormdb.DB.Scopes(m.TableScope, m.Search(c), m.Pagination(c, page)). Find(items).Offset(-1).Limit(-1).Count(&count).Error; err != nil { - api.AddError(err) - api.Log.Errorf("search %s error", c.Param(PathKey)) + api.AddError(err).Log.Error("search error", PathKey, c.Param(PathKey)) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/actions/virtual/update.go b/pkg/response/actions/virtual/update.go index 68776b9..a68c9db 100644 --- a/pkg/response/actions/virtual/update.go +++ b/pkg/response/actions/virtual/update.go @@ -50,8 +50,7 @@ func (e *Update) Handler() gin.HandlerFunc { return } if err := gormdb.DB.Scopes(m.TableScope, m.URI(c)).Updates(req).Error; err != nil { - api.AddError(err) - api.Log.Errorf("update %s error", c.Param(PathKey)) + api.AddError(err).Log.Error("update error", PathKey, c.Param(PathKey)) api.Err(http.StatusInternalServerError) return } diff --git a/pkg/response/return.go b/pkg/response/return.go index 53fde53..b44fd05 100644 --- a/pkg/response/return.go +++ b/pkg/response/return.go @@ -1,11 +1,12 @@ package response import ( + "log/slog" "net/http" + "os" "github.com/gin-gonic/gin" - log "github.com/mss-boot-io/mss-boot/core/logger" "github.com/mss-boot-io/mss-boot/pkg" ) @@ -70,6 +71,7 @@ func PageOK(c *gin.Context, result interface{}, count int64, pageIndex int64, pa func checkContext(c *gin.Context) { if c == nil { - log.Fatalf("context is nil, please check, e.g. e.Make(c) add your controller function") + slog.Error("context is nil, please check, e.g. e.Make(c) add your controller function") + os.Exit(-1) } }