diff --git a/logx/slogx/README.md b/logx/slogx/README.md new file mode 100644 index 0000000..3b292dc --- /dev/null +++ b/logx/slogx/README.md @@ -0,0 +1,80 @@ +### Quick Start + +Prerequesites: + +go version required `1.21` + +- Install `go-zero`: + +```console +go get -u github.com/zeromicro/go-zero +``` + +Download the module: + +```console +go get -u github.com/zeromicro/zero-contrib/logx/slogx +``` + +For example: + +```go +package main + +import ( + "context" + "log/slog" + "os" + "testing" + "time" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/zero-contrib/logx/slogx" +) + +func main() { + h := slog.NewJSONHandler(os.Stdout, nil) + writer := slogx.NewSlogWriter(h) + logx.SetWriter(writer) + + logx.Infow("infow foo", + logx.Field("url", "http://localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.Errorw("errorw foo", + logx.Field("url", "http://localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.Sloww("sloww foo", + logx.Field("url", "http://localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.Error("error") + logx.Infov(map[string]interface{}{ + "url": "localhost:8080/hello", + "attempt": 3, + "backoff": time.Second, + "value": "foo", + }) + logx.WithDuration(1100*time.Microsecond).Infow("infow withduration", + logx.Field("url", "localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.WithContext(context.Background()).WithDuration(1100*time.Microsecond).Errorw( + "errorw withcontext withduration", + logx.Field("url", "localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.WithDuration(1100*time.Microsecond).WithContext(context.Background()).Errorw( + "errorw withduration withcontext", + logx.Field("url", "localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) +} +``` diff --git a/logx/slogx/go.mod b/logx/slogx/go.mod new file mode 100644 index 0000000..4ed5d22 --- /dev/null +++ b/logx/slogx/go.mod @@ -0,0 +1,16 @@ +module slogx + +go 1.21 + +require github.com/zeromicro/go-zero v1.7.2 + +require ( + github.com/fatih/color v1.17.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.uber.org/automaxprocs v1.5.3 // indirect + golang.org/x/sys v0.24.0 // indirect +) diff --git a/logx/slogx/go.sum b/logx/slogx/go.sum new file mode 100644 index 0000000..c8bb24e --- /dev/null +++ b/logx/slogx/go.sum @@ -0,0 +1,43 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/zeromicro/go-zero v1.7.2 h1:a8lyVOG3KXG4LrAy6ZmtJTJtisX4Ostc4Pst4fE704I= +github.com/zeromicro/go-zero v1.7.2/go.mod h1:WFXfF92Exw0O7WECifS6r99JSzv4KEN49x9RhAfgkMc= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/logx/slogx/slog.go b/logx/slogx/slog.go new file mode 100644 index 0000000..9f84a4b --- /dev/null +++ b/logx/slogx/slog.go @@ -0,0 +1,66 @@ +package slogx + +import ( + "fmt" + "log/slog" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SlogWriter struct { + logger *slog.Logger +} + +func NewSlogWriter(handler slog.Handler) logx.Writer { + logger := slog.New(handler) + + return &SlogWriter{ + logger: logger, + } +} + +func (w *SlogWriter) Alert(v interface{}) { + w.logger.Error(fmt.Sprintf("%v", v)) +} + +func (w *SlogWriter) Close() error { + return nil +} + +func (w *SlogWriter) Debug(v interface{}, fields ...logx.LogField) { + w.logger.Debug(fmt.Sprintf("%v", v), toSlogFields(fields...)...) +} + +func (w *SlogWriter) Error(v interface{}, fields ...logx.LogField) { + w.logger.Error(fmt.Sprintf("%v", v), toSlogFields(fields...)...) +} + +func (w *SlogWriter) Info(v interface{}, fields ...logx.LogField) { + w.logger.Info(fmt.Sprintf("%v", v), toSlogFields(fields...)...) +} + +func (w *SlogWriter) Severe(v interface{}) { + w.logger.Error(fmt.Sprintf("%v", v)) +} + +func (w *SlogWriter) Slow(v interface{}, fields ...logx.LogField) { + w.logger.Warn(fmt.Sprintf("%v", v), toSlogFields(fields...)...) +} + +func (w *SlogWriter) Stack(v interface{}) { + w.logger.Error(fmt.Sprintf("%v", v)) +} + +func (w *SlogWriter) Stat(v interface{}, fields ...logx.LogField) { + w.logger.Info(fmt.Sprintf("%v", v), toSlogFields(fields...)...) +} + +func toSlogFields(fields ...logx.LogField) []interface{} { + slogFields := make([]interface{}, len(fields)*2) + for i, field := range fields { + slogFields[i*2] = field.Key + slogFields[i*2+1] = field.Value + } + + return slogFields +} diff --git a/logx/slogx/slog_test.go b/logx/slogx/slog_test.go new file mode 100644 index 0000000..1dcbe0a --- /dev/null +++ b/logx/slogx/slog_test.go @@ -0,0 +1,57 @@ +package slogx + +import ( + "context" + "log/slog" + "os" + "testing" + "time" + + "github.com/zeromicro/go-zero/core/logx" +) + +func TestSlog(t *testing.T) { + h := slog.NewJSONHandler(os.Stdout, nil) + writer := NewSlogWriter(h) + logx.SetWriter(writer) + + logx.Infow("infow foo", + logx.Field("url", "http://localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.Errorw("errorw foo", + logx.Field("url", "http://localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.Sloww("sloww foo", + logx.Field("url", "http://localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.Error("error") + logx.Infov(map[string]interface{}{ + "url": "localhost:8080/hello", + "attempt": 3, + "backoff": time.Second, + "value": "foo", + }) + logx.WithDuration(1100*time.Microsecond).Infow("infow withduration", + logx.Field("url", "localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.WithContext(context.Background()).WithDuration(1100*time.Microsecond).Errorw( + "errorw withcontext withduration", + logx.Field("url", "localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) + logx.WithDuration(1100*time.Microsecond).WithContext(context.Background()).Errorw( + "errorw withduration withcontext", + logx.Field("url", "localhost:8080/hello"), + logx.Field("attempt", 3), + logx.Field("backoff", time.Second), + ) +} \ No newline at end of file