diff --git a/actions/graphql/routes.go b/actions/graphql/routes.go index 2755bac27..aa45dd278 100644 --- a/actions/graphql/routes.go +++ b/actions/graphql/routes.go @@ -5,7 +5,9 @@ import ( "errors" "fmt" "net/http" + "regexp" + "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" "github.com/BuxOrg/bux" @@ -14,6 +16,7 @@ import ( "github.com/BuxOrg/bux-server/dictionary" "github.com/BuxOrg/bux-server/graph" "github.com/BuxOrg/bux-server/graph/generated" + "github.com/gofrs/uuid" "github.com/julienschmidt/httprouter" apirouter "github.com/mrz1836/go-api-router" "github.com/mrz1836/go-logger" @@ -26,6 +29,14 @@ const ( allowOriginHeader string = "Access-Control-Allow-Origin" ) +type requestInfo struct { + id uuid.UUID + method string + path string + ip string + userAgent string +} + // RegisterRoutes register all the package specific routes func RegisterRoutes(router *apirouter.Router, appConfig *config.AppConfig, services *config.AppServices) { @@ -39,12 +50,28 @@ func RegisterRoutes(router *apirouter.Router, appConfig *config.AppConfig, servi serverPath = defaultServerPath } + srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})) + if appConfig.RequestLogging { + re := regexp.MustCompile(`[\r?\n|\s+]`) + srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { + oc := graphql.GetOperationContext(ctx) + reqInfo := ctx.Value(config.GraphRequestInfo).(requestInfo) + params := map[string]interface{}{ + "query": re.ReplaceAllString(oc.RawQuery, " "), + "variables": oc.Variables, + } + // LogParamsFormat "request_id=\"%s\" method=\"%s\" path=\"%s\" ip_address=\"%s\" user_agent=\"%s\" params=\"%v\"\n" + logger.NoFilePrintf(apirouter.LogParamsFormat, reqInfo.id, reqInfo.method, reqInfo.path, reqInfo.ip, reqInfo.userAgent, params) + return next(ctx) + }) + } + // Set the handle h := require.Wrap(wrapHandler( router, a.AppConfig, a.Services, - handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})), + srv, true, )) @@ -124,6 +151,15 @@ func wrapHandler(router *apirouter.Router, appConfig *config.AppConfig, services AuthError: err, }) + guid, _ := uuid.NewV4() + ctx = context.WithValue(ctx, config.GraphRequestInfo, requestInfo{ + id: guid, + method: req.Method, + path: req.RequestURI, + ip: req.RemoteAddr, + userAgent: req.UserAgent(), + }) + // Call your original http.Handler h.ServeHTTP(w, req.WithContext(ctx)) } diff --git a/config/graphql.go b/config/graphql.go index da2bff07a..767c4441d 100644 --- a/config/graphql.go +++ b/config/graphql.go @@ -6,4 +6,7 @@ type graphContextKey string var ( // GraphConfigKey is the ctx key for the GraphConfigKey graphContextKey = "graphql_config" + + // GraphRequestInfo is the ctx key for the request info passed down to graphql for logging + GraphRequestInfo graphContextKey = "request_info" ) diff --git a/go.mod b/go.mod index 1a4cefd55..26584f878 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/BuxOrg/bux v0.2.7 github.com/go-ozzo/ozzo-validation v3.6.0+incompatible github.com/go-redis/redis/v8 v8.11.5 + github.com/gofrs/uuid v4.2.0+incompatible github.com/julienschmidt/httprouter v1.3.0 github.com/mrz1836/go-api-router v0.4.12 github.com/mrz1836/go-logger v0.2.5 @@ -41,7 +42,6 @@ require ( github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/gojektech/heimdall/v6 v6.1.0 // indirect github.com/gojektech/valkyrie v0.0.0-20190210220504-8f62c1e7ba45 // indirect github.com/golang/protobuf v1.5.2 // indirect diff --git a/go.sum b/go.sum index 2f6688b7f..c3c46a7e0 100644 --- a/go.sum +++ b/go.sum @@ -1515,9 +1515,8 @@ google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220407135246-8d918b4c0f5b/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9 h1:XGQ6tc+EnM35IAazg4y6AHmUg4oK8NXsXaILte1vRlk= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4 h1:myaecH64R0bIEDjNORIel4iXubqzaHU1K2z8ajBwWcM= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=