diff options
| author | mo khan <mo@mokhan.ca> | 2025-03-27 11:47:58 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-03-27 11:47:58 -0600 |
| commit | 3faa19c3aeae15070f2e143b031daaddfe296735 (patch) | |
| tree | dc86e49908920c10479b9e9905c58c0c44e2cee6 | |
| parent | b08580ff78708519f0594a62531cf6ce45559265 (diff) | |
feat: start to add structured logging
| -rw-r--r-- | cmd/gtwy/main.go | 5 | ||||
| -rw-r--r-- | go.mod | 4 | ||||
| -rw-r--r-- | go.sum | 11 | ||||
| -rw-r--r-- | pkg/app/app.go | 20 | ||||
| -rw-r--r-- | pkg/authz/token.go | 4 | ||||
| -rw-r--r-- | pkg/cfg/mux.go | 12 | ||||
| -rw-r--r-- | pkg/log/init.go | 29 | ||||
| -rw-r--r-- | pkg/prxy/prxy.go | 6 | ||||
| -rw-r--r-- | pkg/srv/srv.go | 8 |
9 files changed, 79 insertions, 20 deletions
diff --git a/cmd/gtwy/main.go b/cmd/gtwy/main.go index f2a7d2e..f74c030 100644 --- a/cmd/gtwy/main.go +++ b/cmd/gtwy/main.go @@ -1,12 +1,11 @@ package main import ( - "log" - "github.com/xlgmokha/x/pkg/env" "gitlab.com/mokhax/spike/pkg/app" + xlog "gitlab.com/mokhax/spike/pkg/log" ) func main() { - log.Fatal(app.Start(env.Fetch("BIND_ADDR", ":8080"))) + xlog.Default.Fatal(app.Start(env.Fetch("BIND_ADDR", ":8080"))) } @@ -8,6 +8,7 @@ require ( github.com/lestrrat-go/jwx/v3 v3.0.0-alpha3 github.com/magefile/mage v1.15.0 github.com/playwright-community/playwright-go v0.5001.0 + github.com/samber/slog-http v1.6.0 github.com/stretchr/testify v1.10.0 github.com/xlgmokha/x v0.0.0-20240605230110-5cbcac4d8ff8 golang.org/x/oauth2 v0.28.0 @@ -24,6 +25,7 @@ require ( github.com/goccy/go-json v0.10.3 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/jsonapi v1.0.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect @@ -32,6 +34,8 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/segmentio/asm v1.2.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect golang.org/x/crypto v0.36.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/sys v0.31.0 // indirect @@ -24,10 +24,13 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/google/jsonapi v1.0.0 h1:qIGgO5Smu3yJmSs+QlvhQnrscdZfFhiV6S8ryJAglqU= github.com/google/jsonapi v1.0.0/go.mod h1:YYHiRPJT8ARXGER8In9VuLv4qvLfDmA9ULQqptbLE4s= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -54,6 +57,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/samber/slog-http v1.6.0 h1:+rD5QtOWGTcFT7jq8Yf0EgGy87krv0pcgh9jtWkrqjQ= +github.com/samber/slog-http v1.6.0/go.mod h1:PAcQQrYFo5KM7Qbk50gNNwKEAMGCyfsw6GN5dI0iv9g= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -65,6 +70,10 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf github.com/xlgmokha/x v0.0.0-20240605230110-5cbcac4d8ff8 h1:Hmyf8pgNUs3l8TW0YdUarBVAU+hWX87efBukspg4nWc= github.com/xlgmokha/x v0.0.0-20240605230110-5cbcac4d8ff8/go.mod h1:C9MUZ3A7PTPbrLNTvu2lKhpM0dFpPHt5yH8YGuYzmKQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= diff --git a/pkg/app/app.go b/pkg/app/app.go index 35609d7..c55ecce 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -3,7 +3,6 @@ package app import ( "encoding/json" "fmt" - "log" "net" "net/http" "os" @@ -14,6 +13,7 @@ import ( "github.com/xlgmokha/x/pkg/x" "gitlab.com/mokhax/spike/pkg/authz" "gitlab.com/mokhax/spike/pkg/cfg" + xlog "gitlab.com/mokhax/spike/pkg/log" "gitlab.com/mokhax/spike/pkg/srv" ) @@ -23,6 +23,7 @@ func WithCasbin() authz.Authorizer { return authz.AuthorizerFunc(func(r *http.Request) bool { host, _, err := net.SplitHostPort(r.Host) if err != nil { + xlog.WithFields(r, xlog.Fields{"error": err}) return false } @@ -32,11 +33,18 @@ func WithCasbin() authz.Authorizer { } ok, err := enforcer.Enforce(subject, host, r.Method, r.URL.Path) if err != nil { - fmt.Printf("%v\n", err) + xlog.WithFields(r, xlog.Fields{"error": err}) return false } fmt.Printf("%v: %v -> %v %v%v\n", ok, subject, r.Method, host, r.URL.Path) + xlog.WithFields(r, xlog.Fields{ + "ok": ok, + "subject": subject, + "action": r.Method, + "domain": host, + "object": r.URL.Path, + }) return ok }) } @@ -50,8 +58,10 @@ func WithCedar() authz.Authorizer { var entities cedar.EntityMap if err := json.Unmarshal(x.Must(os.ReadFile("cedar.json")), &entities); err != nil { - log.Fatal(err) + xlog.Logger.Error("Error", "error", err) + return nil } + return authz.AuthorizerFunc(func(r *http.Request) bool { host, _, err := net.SplitHostPort(r.Host) if err != nil { @@ -79,9 +89,9 @@ func WithCedar() authz.Authorizer { } func Start(bindAddr string) error { + mux := authz.HTTP(WithCasbin(), Routes()) return srv.Run(cfg.New( bindAddr, - // cfg.WithMux(authz.HTTP(WithCedar(), Routes())), - cfg.WithMux(authz.HTTP(WithCasbin(), Routes())), + cfg.WithMux(mux), )) } diff --git a/pkg/authz/token.go b/pkg/authz/token.go index 1822a21..5985a0f 100644 --- a/pkg/authz/token.go +++ b/pkg/authz/token.go @@ -1,11 +1,11 @@ package authz import ( - "fmt" "net/http" "strings" "github.com/lestrrat-go/jwx/v3/jwt" + xlog "gitlab.com/mokhax/spike/pkg/log" ) func TokenFrom(r *http.Request) jwt.Token { @@ -22,7 +22,7 @@ func TokenFrom(r *http.Request) jwt.Token { ) if err != nil { - fmt.Printf("error: %v\n", err) + xlog.WithFields(r, xlog.Fields{"error": err}) return jwt.New() } diff --git a/pkg/cfg/mux.go b/pkg/cfg/mux.go index 694ee9e..a55b443 100644 --- a/pkg/cfg/mux.go +++ b/pkg/cfg/mux.go @@ -1,9 +1,17 @@ package cfg -import "net/http" +import ( + "net/http" + + sloghttp "github.com/samber/slog-http" + xlog "gitlab.com/mokhax/spike/pkg/log" +) func WithMux(mux http.Handler) Option { return func(config *Config) { - config.Mux = mux + config.Mux = sloghttp.NewWithConfig(xlog.Logger, sloghttp.Config{ + WithSpanID: true, + WithTraceID: true, + })(sloghttp.Recovery(mux)) } } diff --git a/pkg/log/init.go b/pkg/log/init.go new file mode 100644 index 0000000..43ec5ab --- /dev/null +++ b/pkg/log/init.go @@ -0,0 +1,29 @@ +package log + +import ( + "log" + "log/slog" + "net/http" + "os" + + sloghttp "github.com/samber/slog-http" + "github.com/xlgmokha/x/pkg/env" +) + +var Logger *slog.Logger +var Default *log.Logger +var Handler slog.Handler + +func init() { + Handler = slog.NewJSONHandler(os.Stdout, nil) + Logger = slog.New(Handler).With("env", env.Fetch("APP_ENV", "development")) + Default = slog.NewLogLogger(Handler, slog.LevelInfo) +} + +type Fields map[string]interface{} + +func WithFields(r *http.Request, fields Fields) { + for key, value := range fields { + sloghttp.AddCustomAttributes(r, slog.Any(key, value)) + } +} diff --git a/pkg/prxy/prxy.go b/pkg/prxy/prxy.go index 1e378b3..809fdc1 100644 --- a/pkg/prxy/prxy.go +++ b/pkg/prxy/prxy.go @@ -2,13 +2,13 @@ package prxy import ( "fmt" - "log" "net" "net/http" "net/http/httputil" "net/url" "github.com/xlgmokha/x/pkg/x" + xlog "gitlab.com/mokhax/spike/pkg/log" ) func New(routes map[string]string) http.Handler { @@ -21,7 +21,7 @@ func New(routes map[string]string) http.Handler { Rewrite: func(r *httputil.ProxyRequest) { host, _, err := net.SplitHostPort(r.In.Host) if err != nil { - log.Println(err) + xlog.WithFields(r.In, xlog.Fields{"error": err}) return } @@ -37,7 +37,7 @@ func New(routes map[string]string) http.Handler { return nil }, ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) { - log.Println(err) + xlog.WithFields(r, xlog.Fields{"error": err}) }, } } diff --git a/pkg/srv/srv.go b/pkg/srv/srv.go index a6261ef..ccd02e0 100644 --- a/pkg/srv/srv.go +++ b/pkg/srv/srv.go @@ -1,11 +1,11 @@ package srv import ( - "log" "net/http" "time" "gitlab.com/mokhax/spike/pkg/cfg" + xlog "gitlab.com/mokhax/spike/pkg/log" ) func New(c *cfg.Config) *http.Server { @@ -15,9 +15,9 @@ func New(c *cfg.Config) *http.Server { TLSConfig: c.TLS, ReadHeaderTimeout: 10 * time.Second, ReadTimeout: 30 * time.Second, - WriteTimeout: 2 * time.Minute, - IdleTimeout: 5 * time.Minute, - ErrorLog: log.Default(), + WriteTimeout: 30 * time.Second, + IdleTimeout: 30 * time.Second, + ErrorLog: xlog.Default, } } |
