diff --git a/examples/failover/example.go b/examples/failover/example.go deleted file mode 100644 index e7e637b..0000000 --- a/examples/failover/example.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "fmt" - "net" - "time" - - slogmulti "github.com/samber/slog-multi" - "golang.org/x/exp/slog" -) - -func main() { - // ncat -l 1000 -k - // ncat -l 1001 -k - // ncat -l 1002 -k - - logstash1, _ := net.Dial("tcp", "localhost:1000") - logstash2, _ := net.Dial("tcp", "localhost:1001") - logstash3, _ := net.Dial("tcp", "localhost:1002") - - logger := slog.New( - slogmulti.Failover()( - slog.HandlerOptions{}.NewJSONHandler(logstash1), - slog.HandlerOptions{}.NewJSONHandler(logstash2), - slog.HandlerOptions{}.NewJSONHandler(logstash3), - ), - ) - - logger. - With( - slog.Group("user", - slog.String("id", "user-123"), - slog.Time("created_at", time.Now().AddDate(0, 0, -1)), - ), - ). - With("environment", "dev"). - With("error", fmt.Errorf("an error")). - Error("A message") -} diff --git a/examples/fanout/example.go b/examples/fanout/example.go deleted file mode 100644 index 02ba44d..0000000 --- a/examples/fanout/example.go +++ /dev/null @@ -1,66 +0,0 @@ -package main - -import ( - "fmt" - "log" - "net" - "os" - "time" - - slogmulti "github.com/samber/slog-multi" - "golang.org/x/exp/slog" -) - -func connectLogstash() *net.TCPConn { - // ncat -l 4242 -k - addr, err := net.ResolveTCPAddr("tcp", "localhost:4242") - if err != nil { - log.Fatal("TCP connection failed:", err.Error()) - } - - conn, err := net.DialTCP("tcp", nil, addr) - if err != nil { - log.Fatal("TCP connection failed:", err.Error()) - } - - return conn -} - -func main() { - logstash := connectLogstash() - stderr := os.Stderr - - logger := slog.New( - slogmulti.Fanout( - slog.HandlerOptions{}.NewJSONHandler(logstash), - slog.HandlerOptions{}.NewTextHandler(stderr), - ), - ) - - logger. - With( - slog.Group("user", - slog.String("id", "user-123"), - slog.Time("created_at", time.Now().AddDate(0, 0, -1)), - ), - ). - With("environment", "dev"). - With("error", fmt.Errorf("an error")). - Error("A message") - - // stderr output: - // time=2023-04-10T14:00:0.000000+00:00 level=ERROR msg="A message" user.id=user-123 user.created_at=2023-04-10T14:00:0.000000+00:00 environment=dev error="an error" - - // netcat output: - // { - // "time":"2023-04-10T14:00:0.000000+00:00", - // "level":"ERROR", - // "msg":"A message", - // "user":{ - // "id":"user-123", - // "created_at":"2023-04-10T14:00:0.000000+00:00" - // }, - // "environment":"dev", - // "error":"an error" - // } -} diff --git a/examples/pipe/errors.go b/examples/pipe/errors.go deleted file mode 100644 index 69e8d33..0000000 --- a/examples/pipe/errors.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "context" - "reflect" - - "golang.org/x/exp/slog" -) - -func errorFormattingMiddleware(ctx context.Context, record slog.Record, next func(context.Context, slog.Record) error) error { - attrs := []slog.Attr{} - - record.Attrs(func(attr slog.Attr) bool { - key := attr.Key - value := attr.Value - kind := attr.Value.Kind() - - if key == "error" && kind == slog.KindAny { - if err, ok := value.Any().(error); ok { - errType := reflect.TypeOf(err).String() - msg := err.Error() - - attrs = append( - attrs, - slog.Group("error", - slog.String("type", errType), - slog.String("message", msg), - ), - ) - } else { - attrs = append(attrs, attr) - } - } else { - attrs = append(attrs, attr) - } - - return true - }) - - // new record with formatted error - record = slog.NewRecord(record.Time, record.Level, record.Message, record.PC) - record.AddAttrs(attrs...) - - return next(ctx, record) -} diff --git a/examples/pipe/example.go b/examples/pipe/example.go deleted file mode 100644 index fd9e443..0000000 --- a/examples/pipe/example.go +++ /dev/null @@ -1,58 +0,0 @@ -package main - -import ( - "fmt" - "os" - "time" - - slogmulti "github.com/samber/slog-multi" - "golang.org/x/exp/slog" -) - -func main() { - // format go `error` type into an object {error: "*myCustomErrorType", message: "could not reach https://a.b/c"} - errorFormattingMiddleware := slogmulti.NewHandleInlineMiddleware(errorFormattingMiddleware) - - // remove PII - gdprMiddleware := NewGDPRMiddleware() - - sink := slog.HandlerOptions{}.NewJSONHandler(os.Stderr) - - logger := slog.New( - slogmulti. - Pipe(errorFormattingMiddleware). - Pipe(gdprMiddleware). - Handler(sink), - ) - - logger. - With( - slog.Group("user", - slog.String("id", "user-123"), - slog.String("email", "user-123"), - slog.Time("created_at", time.Now()), - ), - ). - With("environment", "dev"). - Error("A message", - slog.String("foo", "bar"), - slog.Any("error", fmt.Errorf("an error"))) - - // output: - // { - // "time":"2023-04-10T14:00:0.000000+00:00", - // "level":"ERROR", - // "msg":"A message", - // "user":{ - // "id":"*******", - // "email":"*******", - // "created_at":"*******" - // }, - // "environment":"dev", - // "foo":"bar", - // "error":{ - // "type":"*errors.errorString", - // "message":"an error" - // } - // } -} diff --git a/examples/pipe/gdpr.go b/examples/pipe/gdpr.go deleted file mode 100644 index cc8b809..0000000 --- a/examples/pipe/gdpr.go +++ /dev/null @@ -1,97 +0,0 @@ -package main - -import ( - "context" - "strings" - - slogmulti "github.com/samber/slog-multi" - "golang.org/x/exp/slog" -) - -func NewGDPRMiddleware() slogmulti.Middleware { - return func(next slog.Handler) slog.Handler { - return &gdprMiddleware{ - next: next, - anonymize: false, - } - } -} - -type gdprMiddleware struct { - next slog.Handler - anonymize bool -} - -func (h *gdprMiddleware) Enabled(ctx context.Context, level slog.Level) bool { - return h.next.Enabled(ctx, level) -} - -func (h *gdprMiddleware) Handle(ctx context.Context, record slog.Record) error { - attrs := []slog.Attr{} - - record.Attrs(func(attr slog.Attr) bool { - if mightContainPII(attr.Key) { - attrs = append(attrs, anonymize(attr)) - } else { - attrs = append(attrs, attr) - } - - return true - }) - - // new record with anonymized data - record = slog.NewRecord(record.Time, record.Level, record.Message, record.PC) - record.AddAttrs(attrs...) - - return h.next.Handle(ctx, record) -} - -func (h *gdprMiddleware) WithAttrs(attrs []slog.Attr) slog.Handler { - if h.anonymize { - for i := range attrs { - attrs[i] = anonymize(attrs[i]) - } - } - - for i := range attrs { - if mightContainPII(attrs[i].Key) { - attrs[i] = anonymize(attrs[i]) - } - } - - return &gdprMiddleware{ - next: h.next.WithAttrs(attrs), - anonymize: h.anonymize, - } -} - -func (h *gdprMiddleware) WithGroup(name string) slog.Handler { - return &gdprMiddleware{ - next: h.next.WithGroup(name), - anonymize: h.anonymize || mightContainPII(name), - } -} - -func mightContainPII(key string) bool { - return key == "user" || - strings.Index(key, "user_") == 0 || - strings.Index(key, "user-") == 0 || - strings.Index(key, "user.") == 0 -} - -func anonymize(attr slog.Attr) slog.Attr { - k := attr.Key - v := attr.Value - kind := attr.Value.Kind() - - switch kind { - case slog.KindGroup: - attrs := v.Group() - for i := range attrs { - attrs[i] = anonymize(attrs[i]) - } - return slog.Group(k, attrs...) - default: - return slog.String(k, "*******") - } -} diff --git a/examples/pool/example.go b/examples/pool/example.go deleted file mode 100644 index 94fe900..0000000 --- a/examples/pool/example.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "fmt" - "net" - "time" - - slogmulti "github.com/samber/slog-multi" - "golang.org/x/exp/slog" -) - -func main() { - // ncat -l 1000 -k - // ncat -l 1001 -k - // ncat -l 1002 -k - - logstash1, _ := net.Dial("tcp", "localhost:1000") - logstash2, _ := net.Dial("tcp", "localhost:1001") - logstash3, _ := net.Dial("tcp", "localhost:1002") - - logger := slog.New( - slogmulti.Pool()( - slog.HandlerOptions{}.NewJSONHandler(logstash1), - slog.HandlerOptions{}.NewJSONHandler(logstash2), - slog.HandlerOptions{}.NewJSONHandler(logstash3), - ), - ) - - logger. - With( - slog.Group("user", - slog.String("id", "user-123"), - slog.Time("created_at", time.Now().AddDate(0, 0, -1)), - ), - ). - With("environment", "dev"). - With("error", fmt.Errorf("an error")). - Error("A message") -} diff --git a/examples/router/example.go b/examples/router/example.go deleted file mode 100644 index cd2275e..0000000 --- a/examples/router/example.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "context" - - slogmulti "github.com/samber/slog-multi" - slogslack "github.com/samber/slog-slack" - "golang.org/x/exp/slog" -) - -func recordMatchRegion(region string) func(ctx context.Context, r slog.Record) bool { - return func(ctx context.Context, r slog.Record) bool { - ok := false - - r.Attrs(func(attr slog.Attr) bool { - if attr.Key == "region" && attr.Value.Kind() == slog.KindString && attr.Value.String() == region { - ok = true - return false - } - - return true - }) - - return ok - } -} - -func main() { - slackChannelUS := slogslack.Option{Level: slog.LevelError, WebhookURL: "xxx", Channel: "supervision-us"}.NewSlackHandler() - slackChannelEU := slogslack.Option{Level: slog.LevelError, WebhookURL: "xxx", Channel: "supervision-eu"}.NewSlackHandler() - slackChannelAPAC := slogslack.Option{Level: slog.LevelError, WebhookURL: "xxx", Channel: "supervision-apac"}.NewSlackHandler() - - logger := slog.New( - slogmulti.Router(). - Add(slackChannelUS, recordMatchRegion("us")). - Add(slackChannelEU, recordMatchRegion("eu")). - Add(slackChannelAPAC, recordMatchRegion("apac")). - Handler(), - ) - - logger. - With("region", "us"). - With("pool", "us-west-1"). - Error("Server desynchronized") -} diff --git a/go.mod b/go.mod index e5b02f9..87b2f68 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,5 @@ go 1.20 require ( github.com/samber/lo v1.38.1 - github.com/samber/slog-slack v0.1.1 golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 ) - -require ( - github.com/gorilla/websocket v1.4.2 // indirect - github.com/slack-go/slack v0.12.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/go.sum b/go.sum index d12eea3..0dac19d 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,4 @@ -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/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= -github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -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/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/samber/slog-slack v0.1.1 h1:h36tHCIeNSX3lPD7wtIfblOem1lanWIh77p0zszrq3I= -github.com/samber/slog-slack v0.1.1/go.mod h1:rXkQmNKcjKhMAAl0cfbH0cnlgveqGXUdoIyYnEmnguQ= -github.com/slack-go/slack v0.12.1 h1:X97b9g2hnITDtNsNe5GkGx6O2/Sz/uC20ejRZN6QxOw= -github.com/slack-go/slack v0.12.1/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -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/images/workflow.drawio b/images/workflow.drawio deleted file mode 100644 index 710abad..0000000 --- a/images/workflow.drawio +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/images/workflow.png b/images/workflow.png deleted file mode 100644 index c44d45d..0000000 Binary files a/images/workflow.png and /dev/null differ