diff --git a/example/go.mod b/example/go.mod new file mode 100644 index 0000000..603303a --- /dev/null +++ b/example/go.mod @@ -0,0 +1,19 @@ +module github.com/carousell/go-logging/example + +go 1.18 + +replace ( + github.com/carousell/go-logging => ../ + github.com/carousell/go-logging/gokit => ../gokit +) + +require ( + github.com/carousell/go-logging v0.0.0-20230322093349-63592a690170 + github.com/carousell/go-logging/gokit v0.0.0-20230322093349-63592a690170 +) + +require ( + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect +) diff --git a/example/go.sum b/example/go.sum new file mode 100644 index 0000000..0388088 --- /dev/null +++ b/example/go.sum @@ -0,0 +1,10 @@ +github.com/carousell/go-logging v0.0.0-20230322093349-63592a690170 h1:2a4U/3KXreDg6xECAsY+/HnvubSDLMQzAYtKNBXUQOo= +github.com/carousell/go-logging v0.0.0-20230322093349-63592a690170/go.mod h1:rNIbSrWZ+PZyl3NJIC1g8UyFA1gjMJxHdBhqDFdNs1w= +github.com/carousell/go-logging/gokit v0.0.0-20230322093349-63592a690170 h1:/NMBf7No4l+VjPolLYSeobAYiniqoBpo+QgSdBvUxD4= +github.com/carousell/go-logging/gokit v0.0.0-20230322093349-63592a690170/go.mod h1:JQioIqeAAjr9n/7vWDeqKczZ7wqSMhrN+fKapvmTEsk= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= diff --git a/example/main.go b/example/main.go new file mode 100644 index 0000000..dbac7f8 --- /dev/null +++ b/example/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "context" + + "github.com/carousell/go-logging" + "github.com/carousell/go-logging/gokit" +) + +func main() { + + ctx := context.Background() + + logging.RegisterLogger(gokit.NewLogger()) + + ctx = logging.WithLogger(ctx, + logging.WithAttr("main1", "main1"), + logging.WithAttr("main2", 123), + ) + + logging.InfoV2(ctx, "before calling foo()") + //{"@timestamp":"2023-04-27T00:39:45.573743+08:00","caller":"go-logging/new.go:33","level":"info","main1":"main1","main2":123,"msg":"before calling foo()"} + + foo(ctx) + logging.InfoV2(ctx, "after called foo()") + //{"@timestamp":"2023-04-27T00:39:45.574079+08:00","caller":"go-logging/new.go:33","level":"info","main1":"main1","main2":123,"msg":"after called foo()"} + + logging.InfoV3(ctx, "msg v3 without attributes", nil) + //{"@timestamp":"2023-04-27T00:01:39.701337+05:30","caller":"go-logging/new.go:35","level":"info","main1":"main1","main2":123,"msg":"msg v3 without attributes"} + + logging.InfoV3(ctx, "msg v3", logging.AttrMap{"listing_id": "1000323749", "is_exp_enabled": true}) + //{"@timestamp":"2023-04-27T00:04:01.998833+05:30","caller":"go-logging/new.go:35","is_exp_enabled":true,"level":"info","listing_id":"1000323749","main1":"main1","main2":123,"msg":"msg v3"} +} + +func foo(ctx context.Context) { + ctx = logging.WithLogger(ctx, + logging.WithAttr("foo1", "foo1"), + logging.WithAttr("foo2", 456), + ) + + logging.InfoV2(ctx, "before calling bar()", logging.WithAttr("foo3", "foo3")) + //{"@timestamp":"2023-04-27T00:39:45.574018+08:00","caller":"go-logging/new.go:33","level":"info","main1":"main1","main2":123,"foo1":"foo1","foo2":456,"foo3":"foo3","msg":"before calling bar()"} + + bar(ctx) + + logging.InfoV2(ctx, "after called bar()", logging.WithAttr("result", "bar result")) + //{"@timestamp":"2023-04-27T00:39:45.574068+08:00","caller":"go-logging/new.go:33","level":"info","main1":"main1","main2":123,"foo1":"foo1","foo2":456,"result":"bar result","msg":"after called bar()"} +} + +func bar(ctx context.Context) { + ctx = logging.WithLogger(ctx, + logging.WithAttr("bar1", "bar1"), + logging.WithAttr("bar2", 789), + ) + logging.InfoV2(ctx, "before do something", logging.WithAttr("bar3", 9876)) + //{"@timestamp":"2023-04-27T00:39:45.574037+08:00","caller":"go-logging/new.go:33","level":"info","main1":"main1","main2":123,"foo1":"foo1","foo2":456,"bar1":"bar1","bar2":789,"bar3":9876,"msg":"before do something"} + + logging.InfoV2(ctx, "after do something", logging.WithAttr("result", "success")) + //{"@timestamp":"2023-04-27T00:39:45.574055+08:00","caller":"go-logging/new.go:33","level":"info","main1":"main1","main2":123,"foo1":"foo1","foo2":456,"bar1":"bar1","bar2":789,"result":"success","msg":"after do something"} +} diff --git a/new.go b/new.go new file mode 100644 index 0000000..9ca27d6 --- /dev/null +++ b/new.go @@ -0,0 +1,89 @@ +package logging + +import ( + "context" +) + +type Attr [2]interface{} + +type AttrMap map[string]interface{} + +type LoggerV2 interface { + Info(ctx context.Context, msg string, attrs ...Attr) +} + +func NewLoggerV2(baseLogger BaseLogger) LoggerV2 { + return loggerV2{ + baseLogger: baseLogger, + } +} + +type loggerV2 struct { + baseLogger BaseLogger + + attrs []Attr +} + +func (l loggerV2) log(ctx context.Context, level Level, msg string, attrs ...Attr) { + args := attrsToArgs(l.attrs) + args = append(args, attrsToArgs(attrs)...) + args = append(args, "msg", msg) + l.baseLogger.Log(ctx, level, 1, args...) +} + +func (l loggerV2) Info(ctx context.Context, msg string, attrs ...Attr) { + l.log(ctx, InfoLevel, msg, attrs...) +} + +type loggerKeyType struct{} + +var loggerKey loggerKeyType = struct{}{} + +func WithLogger(ctx context.Context, attrs ...Attr) context.Context { + if parentLogger, ok := GetLoggerV2(ctx).(loggerV2); ok { + attrs = append(attrs, parentLogger.attrs...) + } + + logger := loggerV2{ + baseLogger: globalLogger, + attrs: attrs, + } + + ctx = context.WithValue(ctx, loggerKey, logger) + + return ctx +} + +func GetLoggerV2(ctx context.Context) LoggerV2 { + logger, ok := ctx.Value(loggerKey).(LoggerV2) + if !ok { + return NewLoggerV2(globalLogger) + } + return logger +} + +func InfoV2(ctx context.Context, msg string, attrs ...Attr) { + logger := GetLoggerV2(ctx) + logger.Info(ctx, msg, attrs...) +} + +func InfoV3(ctx context.Context, msg string, attrs AttrMap) { + logger := GetLoggerV2(ctx) + var args []Attr + for k, v := range attrs { + args = append(args, WithAttr(k, v)) + } + logger.Info(ctx, msg, args...) +} + +func WithAttr(key string, value interface{}) Attr { + return [2]interface{}{key, value} +} + +func attrsToArgs(attrs []Attr) []interface{} { + args := make([]interface{}, 0, len(attrs)*2) + for _, attr := range attrs { + args = append(args, attr[0], attr[1]) + } + return args +}