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 cf5493a..0000000 --- a/examples/pipe/errors.go +++ /dev/null @@ -1,43 +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) { - 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) - } - }) - - // 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 c86a63e..0000000 --- a/examples/pipe/gdpr.go +++ /dev/null @@ -1,95 +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) { - if mightContainPII(attr.Key) { - attrs = append(attrs, anonymize(attr)) - } else { - attrs = append(attrs, attr) - } - }) - - // 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/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