diff --git a/README.md b/README.md index 69391226..1ed038e3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Micro -![Coverage](https://img.shields.io/badge/Coverage-44.9%25-yellow) +![Coverage](https://img.shields.io/badge/Coverage-45.1%25-yellow) Micro is a standard library for microservices. diff --git a/codec/codec.go b/codec/codec.go index b850cf8f..5f8cb66b 100644 --- a/codec/codec.go +++ b/codec/codec.go @@ -3,6 +3,8 @@ package codec import ( "errors" + + "gopkg.in/yaml.v3" ) var ( @@ -54,3 +56,22 @@ func (m *RawMessage) UnmarshalJSON(data []byte) error { *m = append((*m)[0:0], data...) return nil } + +// MarshalYAML returns m as the JSON encoding of m. +func (m *RawMessage) MarshalYAML() ([]byte, error) { + if m == nil { + return []byte("null"), nil + } else if len(*m) == 0 { + return []byte("null"), nil + } + return *m, nil +} + +// UnmarshalYAML sets *m to a copy of data. +func (m *RawMessage) UnmarshalYAML(n *yaml.Node) error { + if m == nil { + return errors.New("RawMessage UnmarshalYAML on nil pointer") + } + *m = append((*m)[0:0], []byte(n.Value)...) + return nil +} diff --git a/codec/frame.go b/codec/frame.go index 133e690c..4bf0f138 100644 --- a/codec/frame.go +++ b/codec/frame.go @@ -1,5 +1,7 @@ package codec +import "gopkg.in/yaml.v3" + // Frame gives us the ability to define raw data to send over the pipes type Frame struct { Data []byte @@ -20,6 +22,17 @@ func (m *Frame) UnmarshalJSON(data []byte) error { return m.Unmarshal(data) } +// MarshalYAML returns frame data +func (m *Frame) MarshalYAML() ([]byte, error) { + return m.Marshal() +} + +// UnmarshalYAML set frame data +func (m *Frame) UnmarshalYAML(n *yaml.Node) error { + m.Data = []byte(n.Value) + return nil +} + // ProtoMessage noop func func (m *Frame) ProtoMessage() {} diff --git a/go.mod b/go.mod index 36368918..b164472b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module go.unistack.org/micro/v3 -go 1.23.4 +go 1.22.2 require ( dario.cat/mergo v1.0.1 @@ -14,8 +14,8 @@ require ( go.uber.org/automaxprocs v1.6.0 go.unistack.org/micro-proto/v3 v3.4.1 golang.org/x/sync v0.10.0 - google.golang.org/grpc v1.68.1 - google.golang.org/protobuf v1.35.2 + google.golang.org/grpc v1.69.2 + google.golang.org/protobuf v1.36.1 gopkg.in/yaml.v3 v3.0.1 ) @@ -36,8 +36,8 @@ require ( github.com/stretchr/testify v1.10.0 // indirect go.uber.org/goleak v1.3.0 // indirect golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index e3dc57a4..59f72f82 100644 --- a/go.sum +++ b/go.sum @@ -79,8 +79,8 @@ go.unistack.org/micro-proto/v3 v3.4.1 h1:UTjLSRz2YZuaHk9iSlVqqsA50JQNAEK2ZFboGqt go.unistack.org/micro-proto/v3 v3.4.1/go.mod h1:okx/cnOhzuCX0ggl/vToatbCupi0O44diiiLLsZ93Zo= golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -88,12 +88,12 @@ golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= -google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 h1:Z7FRVJPSMaHQxD0uXU8WdgFh8PseLM8Q8NzhnpMrBhQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= +google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= +google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/logger/slog/slog.go b/logger/slog/slog.go index 63cc20bf..1f6589db 100644 --- a/logger/slog/slog.go +++ b/logger/slog/slog.go @@ -22,6 +22,7 @@ const ( badKey = "!BADKEY" // defaultCallerSkipCount used by logger defaultCallerSkipCount = 3 + timeFormat = "2006-01-02T15:04:05.000000000Z07:00" ) var reTrace = regexp.MustCompile(`.*/slog/logger\.go.*\n`) @@ -64,6 +65,7 @@ func (s *slogLogger) renameAttr(_ []string, a slog.Attr) slog.Attr { a.Key = s.opts.SourceKey case slog.TimeKey: a.Key = s.opts.TimeKey + a.Value = slog.StringValue(a.Value.Time().Format(timeFormat)) case slog.MessageKey: a.Key = s.opts.MessageKey case slog.LevelKey: diff --git a/logger/slog/slog_test.go b/logger/slog/slog_test.go index 5032a392..d527110c 100644 --- a/logger/slog/slog_test.go +++ b/logger/slog/slog_test.go @@ -9,12 +9,34 @@ import ( "log/slog" "strings" "testing" + "time" "github.com/google/uuid" "go.unistack.org/micro/v3/logger" "go.unistack.org/micro/v3/metadata" ) +func TestTime(t *testing.T) { + ctx := context.TODO() + buf := bytes.NewBuffer(nil) + l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), + WithHandlerFunc(slog.NewTextHandler), + logger.WithAddStacktrace(true), + logger.WithTimeFunc(func() time.Time { + return time.Unix(0, 0) + }), + ) + if err := l.Init(logger.WithFields("key1", "val1")); err != nil { + t.Fatal(err) + } + + l.Error(ctx, "msg1", errors.New("err")) + + if !bytes.Contains(buf.Bytes(), []byte(`timestamp=1970-01-01T03:00:00.000000000+03:00`)) { + t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) + } +} + func TestStacktrace(t *testing.T) { ctx := context.TODO() buf := bytes.NewBuffer(nil) @@ -28,7 +50,7 @@ func TestStacktrace(t *testing.T) { l.Error(ctx, "msg1", errors.New("err")) - if !bytes.Contains(buf.Bytes(), []byte(`slog_test.go:29`)) { + if !bytes.Contains(buf.Bytes(), []byte(`slog_test.go:51`)) { t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) } }