From 0cac1720beb6441a56ef00ddc9e30cc8ee867875 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Mon, 8 Nov 2021 13:44:32 -0500 Subject: [PATCH 01/14] feat: add interceptor pkg --- pkg/interceptor/interceptor.go | 75 ++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 pkg/interceptor/interceptor.go diff --git a/pkg/interceptor/interceptor.go b/pkg/interceptor/interceptor.go new file mode 100644 index 0000000..edf9a09 --- /dev/null +++ b/pkg/interceptor/interceptor.go @@ -0,0 +1,75 @@ +package interceptor + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" +) + +// Can be use this +// c := &http.Client{ +// Transport: Interceptor{http.DefaultTransport}, +// } + +type Interceptor struct { + core http.RoundTripper +} + +func (Interceptor) ModifyRequest(r *http.Request) *http.Request { + reqBody := MustHumanize(r.Body) + + // this is the request modification + modReqBody := []byte(fmt.Sprintf(`{"req": %s}`, reqBody)) + ModReqBodyLen := len(modReqBody) + + req := r.Clone(context.Background()) + req.Body = io.NopCloser(bytes.NewReader(modReqBody)) + req.ContentLength = int64(ModReqBodyLen) + req.Header.Set("Content-Length", fmt.Sprintf("%d", ModReqBodyLen)) + + return req +} + +func (Interceptor) ModifyResponse(r *http.Response) *http.Response { + respBody := MustHumanize(r.Body) + + // this is the response modification + modRespBody := []byte(fmt.Sprintf(`{"resp": %s}`, respBody)) + ModRespBodyLen := len(modRespBody) + + r.Body = io.NopCloser(bytes.NewReader(modRespBody)) + r.ContentLength = int64(ModRespBodyLen) + r.Header.Set("Content-Length", fmt.Sprintf("%d", ModRespBodyLen)) + + return r +} + +func (i Interceptor) RoundTrip(r *http.Request) (*http.Response, error) { + defer func() { + _ = r.Body.Close() + }() + + // modify before the request is sent + newReq := i.ModifyRequest(r) + + // send the request using the DefaultTransport + resp, _ := i.core.RoundTrip(newReq) + defer func() { + _ = resp.Body.Close() + }() + + // modify after the response is received + newResp := i.ModifyResponse(resp) + + return newResp, nil +} + +func MustHumanize(r io.Reader) string { + var m map[string]interface{} + _ = json.NewDecoder(r).Decode(&m) + b, _ := json.MarshalIndent(m, "", " ") + return string(b) +} From 5d081e2d35a01d64718b779cc2fe4af14ba97afd Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 09:32:13 -0500 Subject: [PATCH 02/14] ref: change zap config to send data to log file with rotation strategy --- .gitignore | 4 +++- go.mod | 1 + go.sum | 2 ++ ngonx.yaml | 4 ++-- pkg/logger/logger.go | 25 ++++++++++++++++++------- scripts/request/micro-a.rest | 4 ++-- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 77f33f1..641b954 100755 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,6 @@ build *.key *.pem *.csr -dist \ No newline at end of file +dist +ngonx-log +observability diff --git a/go.mod b/go.mod index 052ff67..cfc0627 100644 --- a/go.mod +++ b/go.mod @@ -21,4 +21,5 @@ require ( golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect golang.org/x/sys v0.0.0-20211031064116-611d5d643895 // indirect google.golang.org/grpc v1.40.0 + gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) diff --git a/go.sum b/go.sum index d9d86a9..2bd4fb4 100644 --- a/go.sum +++ b/go.sum @@ -771,6 +771,8 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8 gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/ngonx.yaml b/ngonx.yaml index 6428edc..2341187 100644 --- a/ngonx.yaml +++ b/ngonx.yaml @@ -38,7 +38,7 @@ proxy: # maps of microservices with routes services_proxy: - name: microA - host_uri: http://localhost:3000 + host_uri: http://localhost:3001 endpoints: - path_endpoints: /api/v1/health/ path_proxy: /health/ @@ -48,7 +48,7 @@ proxy: path_proxy: /version/ path_protected: true - name: microB - host_uri: http://localhost:4000 + host_uri: http://localhost:4001 endpoints: - path_endpoints: /api/v1/health/ path_proxy: /ready/ diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index aab5041..d658005 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -3,23 +3,34 @@ package logger import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" + "gopkg.in/natefinch/lumberjack.v2" ) var log *zap.Logger func init() { - var err error - config := zap.NewProductionConfig() + // var err error + // config := zap.NewProductionConfig() encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.TimeKey = "timestamp" encoderConfig.StacktraceKey = "" encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - config.EncoderConfig = encoderConfig - log, err = config.Build(zap.AddCallerSkip(1)) - if err != nil { - panic(err) - } + // lumberjack.Logger is already safe for concurrent use, so we don't need to + // lock it. + w := zapcore.AddSync(&lumberjack.Logger{ + Filename: "./ngonx-log/ngonx.log", + MaxSize: 500, // megabytes + MaxBackups: 3, + MaxAge: 28, // days + }) + core := zapcore.NewCore( + zapcore.NewConsoleEncoder(encoderConfig), + w, + zap.InfoLevel, + ) + log = zap.New(core) + } // LogInfo wrap for log.info diff --git a/scripts/request/micro-a.rest b/scripts/request/micro-a.rest index 54e6a40..118a3d1 100644 --- a/scripts/request/micro-a.rest +++ b/scripts/request/micro-a.rest @@ -1,10 +1,10 @@ ### Micro A -GET http://localhost:3000/api/v1/health/ +GET http://localhost:3001/api/v1/health/ ### -GET http://localhost:3000/api/v1/version/ +GET http://localhost:3001/api/v1/version/ ### Gateway Proxy From 7fa706d53d934f6ec540378b4438151b15e68332 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 09:42:16 -0500 Subject: [PATCH 03/14] ref: add log formating to grpc cmd --- cmd/cli/grpcxy.go | 15 ++++++++------- pkg/logger/logger.go | 5 +---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/cmd/cli/grpcxy.go b/cmd/cli/grpcxy.go index afb9ccf..0653af6 100644 --- a/cmd/cli/grpcxy.go +++ b/cmd/cli/grpcxy.go @@ -3,13 +3,13 @@ package cli import ( "context" "fmt" - "log" "net" "os" "os/signal" "strings" "time" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" "github.com/spf13/cobra" "github.com/talos-systems/grpc-proxy/proxy" @@ -29,7 +29,7 @@ var grpcCmd = &cobra.Command{ lis, err := net.Listen("tcp", configFromYaml.GrpcProxy.Listener) if err != nil { - log.Fatalf("failed to listen: %v", err) + logger.LogError(errors.Errorf("grpc: failed to listen: %v", err).Error()) } logger.LogInfo(fmt.Sprintf("Proxy running at %q\n", configFromYaml.GrpcProxy.Listener)) @@ -43,7 +43,7 @@ var grpcCmd = &cobra.Command{ creds, sslErr := credentials.NewClientTLSFromFile( configFromYaml.GrpcClientCert, "") if sslErr != nil { - log.Fatalf("Failed to parse credentials: %v", sslErr) + logger.LogError(errors.Errorf("grpc: failed to parse credentials: %v", sslErr).Error()) } conn, err := grpc.DialContext( ctx, @@ -94,7 +94,7 @@ var grpcCmd = &cobra.Command{ configFromYaml.GrpcSSL.KeyFile, ) if sslErr != nil { - log.Fatalf("Failed to parse credentials: %v", sslErr) + logger.LogError(errors.Errorf("grpc: failed to parse credentials: %v", sslErr).Error()) return } opts = append(opts, grpc.Creds(creds)) @@ -104,7 +104,7 @@ var grpcCmd = &cobra.Command{ go gracefulShutdown(server) if err := server.Serve(lis); err != nil { - log.Fatalf("failed to serve: %v", err) + logger.LogError(errors.Errorf("grpc: failed to serve: %v", err).Error()) } }, } @@ -119,11 +119,12 @@ func gracefulShutdown(server *grpc.Server) { signal.Notify(quit, os.Interrupt) sig := <-quit - logger.LogInfo(fmt.Sprintf("server is shutting down %s", sig.String())) + logger.LogWarn(fmt.Sprintf("grpc: server is shutting down %s", sig.String())) _, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() server.GracefulStop() - logger.LogInfo("server stopped") + logger.LogWarn(fmt.Sprintf("grpc: server is shutting down %s", sig.String())) + } diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index d658005..11f0aae 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -9,15 +9,12 @@ import ( var log *zap.Logger func init() { - // var err error - // config := zap.NewProductionConfig() + encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.TimeKey = "timestamp" encoderConfig.StacktraceKey = "" encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - // lumberjack.Logger is already safe for concurrent use, so we don't need to - // lock it. w := zapcore.AddSync(&lumberjack.Logger{ Filename: "./ngonx-log/ngonx.log", MaxSize: 500, // megabytes From 4e85d3144ae3970c10da96f3e956f4636dfed85e Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 09:45:08 -0500 Subject: [PATCH 04/14] ref: change log format --- cmd/cli/lb.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/cmd/cli/lb.go b/cmd/cli/lb.go index d48a1c3..e13af5c 100644 --- a/cmd/cli/lb.go +++ b/cmd/cli/lb.go @@ -14,6 +14,7 @@ import ( handlers "github.com/kenriortega/ngonx/internal/proxy/handlers" "github.com/kenriortega/ngonx/pkg/backoff" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" "github.com/spf13/cobra" ) @@ -30,14 +31,14 @@ var lbCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { port, err := cmd.Flags().GetInt(flagPort) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("lb: %v", err).Error()) } serverList, err := cmd.Flags().GetString(flagServerList) if err != nil { log.Fatalf(err.Error()) } if len(serverList) == 0 { - log.Fatal("Please provide one or more backends to load balance") + logger.LogError(errors.Errorf("lb: provide one or more backends to load balance %v", err).Error()) } // parse servers @@ -45,12 +46,12 @@ var lbCmd = &cobra.Command{ for _, tok := range tokens { serverUrl, err := url.Parse(tok) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("lb: %v", err).Error()) } proxy := httputil.NewSingleHostReverseProxy(serverUrl) proxy.ErrorHandler = func(writer http.ResponseWriter, request *http.Request, e error) { - logger.LogInfo(fmt.Sprintf("[%s] %s\n", serverUrl.Host, e.Error())) + logger.LogInfo(fmt.Sprintf("lb: %s %s\n", serverUrl.Host, e.Error())) retry := handlers.GetRetryFromContext(request) if retry < 3 { @@ -66,7 +67,7 @@ var lbCmd = &cobra.Command{ // if the same request routing for few attempts with different backends, increase the count attempts := handlers.GetAttemptsFromContext(request) - logger.LogInfo(fmt.Sprintf("%s(%s) Attempting retry %d\n", request.RemoteAddr, request.URL.Path, attempts)) + logger.LogInfo(fmt.Sprintf("lb: %s(%s) Attempting retry %d\n", request.RemoteAddr, request.URL.Path, attempts)) ctx := context.WithValue(request.Context(), domain.ATTEMPTS, attempts+1) handlers.Lbalancer(writer, request.WithContext(ctx)) } @@ -76,7 +77,7 @@ var lbCmd = &cobra.Command{ Alive: true, ReverseProxy: proxy, }) - logger.LogInfo(fmt.Sprintf("Configured server: %s\n", serverUrl)) + logger.LogInfo(fmt.Sprintf("lb: configured server: %s\n", serverUrl)) } // create http server @@ -88,9 +89,9 @@ var lbCmd = &cobra.Command{ // start health checking go handlers.HealthCheck() - logger.LogInfo(fmt.Sprintf("Load Balancer started at :%d\n", port)) + logger.LogInfo(fmt.Sprintf("lb: Load Balancer started at :%d\n", port)) if err := server.ListenAndServe(); err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("lb: %v", err).Error()) } }, From d9b34f0cbbac964489d4dcc14c92aef07ce9cf1c Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 09:52:27 -0500 Subject: [PATCH 05/14] ref: change log format --- cmd/cli/proxy.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cmd/cli/proxy.go b/cmd/cli/proxy.go index ba3208f..449308c 100644 --- a/cmd/cli/proxy.go +++ b/cmd/cli/proxy.go @@ -5,6 +5,7 @@ import ( handlers "github.com/kenriortega/ngonx/internal/proxy/handlers" services "github.com/kenriortega/ngonx/internal/proxy/services" "github.com/kenriortega/ngonx/pkg/badgerdb" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/genkey" "github.com/kenriortega/ngonx/pkg/httpsrv" "github.com/kenriortega/ngonx/pkg/logger" @@ -18,15 +19,15 @@ var proxyCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { port, err := cmd.Flags().GetInt(flagPort) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("proxy: %v", err).Error()) } generateApiKey, err := cmd.Flags().GetBool(flagGenApiKey) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("proxy: %v", err).Error()) } prevKey, err := cmd.Flags().GetString(flagPrevKey) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("proxy: %v", err).Error()) } // Exporter Metrics go metric.ExposeMetricServer(configFromYaml.ProxyGateway.PortExporterProxy) @@ -47,16 +48,16 @@ var proxyCmd = &cobra.Command{ apiKey := genkey.ApiKeyGenerator(word) _, err := h.Service.SaveSecretKEY(engine, key, apiKey) if err != nil { - logger.LogError("genkey: Failed " + err.Error()) + logger.LogError(errors.Errorf("proxy: failed genkey cmd %v", err).Error()) } - logger.LogInfo("genkey: Susscefull") + logger.LogInfo("proxy: genkey cmd was susscefull") } if prevKey != "" { _, err := h.Service.SaveSecretKEY(engine, key, prevKey) if err != nil { - logger.LogError("prevKey: Failed " + err.Error()) + logger.LogError(errors.Errorf("proxy: failed prevKey cmd %v", err).Error()) } - logger.LogInfo("prevKey: Susscefull") + logger.LogInfo("proxy: prevKey cmd was Susscefull") } for _, endpoints := range configFromYaml.ProxyGateway.EnpointsProxy { From 1139d7361ee1c58b515d9d68cc32ccb3471ab9b8 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 09:56:36 -0500 Subject: [PATCH 06/14] ref: change log format --- cmd/cli/root.go | 9 +++++---- pkg/errors/customsErrors.go | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cmd/cli/root.go b/cmd/cli/root.go index 7136c48..7b9dbd2 100644 --- a/cmd/cli/root.go +++ b/cmd/cli/root.go @@ -13,6 +13,7 @@ import ( handlers "github.com/kenriortega/ngonx/internal/mngt/handlers" services "github.com/kenriortega/ngonx/internal/mngt/services" "github.com/kenriortega/ngonx/pkg/config" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/healthcheck" "github.com/kenriortega/ngonx/pkg/httpsrv" "github.com/kenriortega/ngonx/pkg/logger" @@ -70,7 +71,7 @@ func initConfig() { configFromYaml, errConfig = config.LoadConfig(cfgPath, cfgFile) if errConfig != nil { - logger.LogError("Yaml file not found please run command setup " + errConfig.Error()) + logger.LogError(errors.Errorf("ngonx: Yaml file not found please run command setup :%v", errConfig).Error()) } go StartMngt(configFromYaml) @@ -80,7 +81,7 @@ func StartMngt(config config.Config) { stripped, err := fs.Sub(frontend, "ui") if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx: :%v", err).Error()) } frontendFS := http.FileServer(http.FS(stripped)) @@ -125,12 +126,12 @@ func StartMngt(config config.Config) { endpoints, err := service.ListEndpoints() if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx: :%v", err).Error()) } for _, it := range endpoints { u, err := url.Parse(it.PathUrl) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx: :%v", err).Error()) } status := healthcheck.IsBackendAlive(u) if status { diff --git a/pkg/errors/customsErrors.go b/pkg/errors/customsErrors.go index f8fbb28..bc12d30 100644 --- a/pkg/errors/customsErrors.go +++ b/pkg/errors/customsErrors.go @@ -9,7 +9,7 @@ var ( ErrCreatingSettingFile = NewError("security: error on create setting file") ErrWritingSettingFile = NewError("security: error on write setting file") // loadbalancer - ErrIsBackendAlive = NewError("lb: Site unreachcable dial tcp") + ErrIsBackendAlive = NewError("ngonx healthcheck: Site unreachcable dial tcp") // repositoryDB ErrSavekeyUpdateTX = NewError("badgerdb: error executing TX to save apikey") ErrSavekeyUpdate = NewError("badgerdb: error to save apikey") @@ -19,7 +19,7 @@ var ( ErrGetkeyValue = NewError("baderdb: error executing get item value") ErrGetkeyView = NewError("baderdb: error executing get view") // lbHandler - ErrLBHttp = NewError("lbHandler: error service not availeble") + ErrLBHttp = NewError("lb: error service not availeble") ErrBearerTokenFormat = NewError("proxyHandler: error Format is Authorization: Bearer [token]") ErrTokenExpValidation = NewError("proxyHandler: error token expired") ErrTokenHMACValidation = NewError("proxyHandler: error HMAC verification failed") From 1f603e4210f40a903c452f61dfd0eba643f00df3 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 10:03:02 -0500 Subject: [PATCH 07/14] ref: change log format --- cmd/cli/setup.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/cli/setup.go b/cmd/cli/setup.go index 8e2f555..8c892a1 100644 --- a/cmd/cli/setup.go +++ b/cmd/cli/setup.go @@ -1,8 +1,8 @@ package cli import ( - "log" - + "github.com/kenriortega/ngonx/pkg/errors" + "github.com/kenriortega/ngonx/pkg/logger" "github.com/spf13/cobra" ) @@ -12,7 +12,8 @@ var setupCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { settingsFile, err := cmd.Flags().GetString(flagCfgFile) if err != nil { - log.Fatalf(err.Error()) + logger.LogError(errors.Errorf("ngonx: :%v", err).Error()) + } configFromYaml.CreateSettingFile(settingsFile) From 08a63e4337552f3292a1f3d423a04ff61353d720 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 10:07:36 -0500 Subject: [PATCH 08/14] ref: add log format --- internal/mngt/domain/endpoint.go | 7 +++++-- internal/mngt/handlers/mngt.go | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/internal/mngt/domain/endpoint.go b/internal/mngt/domain/endpoint.go index d8308cf..6ec6a93 100644 --- a/internal/mngt/domain/endpoint.go +++ b/internal/mngt/domain/endpoint.go @@ -3,6 +3,7 @@ package mngt import ( "encoding/json" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" uuid "github.com/satori/go.uuid" ) @@ -31,12 +32,14 @@ func NewEnpoint(pathUrl, status string) Endpoint { func (ed *Endpoint) FromMapToJSON(data map[string]interface{}) { b, err := json.Marshal(data) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx mngt: :%v", err).Error()) + } err = json.Unmarshal(b, &ed) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx mngt: :%v", err).Error()) + } } func (ed *Endpoint) ToMAP() (toHashMap map[string]interface{}, err error) { diff --git a/internal/mngt/handlers/mngt.go b/internal/mngt/handlers/mngt.go index 86eddca..fd7c782 100644 --- a/internal/mngt/handlers/mngt.go +++ b/internal/mngt/handlers/mngt.go @@ -2,13 +2,13 @@ package mngt import ( "encoding/json" - "log" "net/http" "time" "github.com/gorilla/websocket" domain "github.com/kenriortega/ngonx/internal/mngt/domain" services "github.com/kenriortega/ngonx/internal/mngt/services" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" ) @@ -36,7 +36,8 @@ func (mh MngtHandler) GetAllEndpoints(w http.ResponseWriter, r *http.Request) { endpoints, err := mh.service.ListEndpoints() if err != nil { - logger.LogError("handler: " + err.Error()) + logger.LogError(errors.Errorf("ngonx mngt: :%v", err).Error()) + writeResponse(w, http.StatusInternalServerError, err) } @@ -53,7 +54,7 @@ func (mh MngtHandler) RegisterEndpoint(data map[string]interface{}) { endpoint.FromMapToJSON(data) err := mh.service.RegisterEndpoint(endpoint) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx mngt: :%v", err).Error()) } } @@ -61,7 +62,7 @@ func (mh MngtHandler) UpdateEndpoint(endpoint domain.Endpoint) { err := mh.service.UpdateEndpoint(endpoint) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx mngt: :%v", err).Error()) } } @@ -71,7 +72,7 @@ func writeResponse(w http.ResponseWriter, code int, data interface{}) { w.Header().Add("Content-Type", "application/json") err := json.NewEncoder(w).Encode(data) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("ngonx mngt: :%v", err).Error()) } } @@ -85,7 +86,7 @@ func (mh MngtHandler) WssocketHandler(w http.ResponseWriter, r *http.Request) { } c, err := upgrader.Upgrade(w, r, nil) if err != nil { - log.Print("upgrade:", err) + logger.LogError(errors.Errorf("ngonx mngt: upgrade ws :%v", err).Error()) return } defer c.Close() @@ -94,7 +95,7 @@ func (mh MngtHandler) WssocketHandler(w http.ResponseWriter, r *http.Request) { mt, message, err := c.ReadMessage() if err != nil { - log.Println("read:", err) + logger.LogError(errors.Errorf("ngonx mngt: read ws :%v", err).Error()) break } switch string(message) { @@ -104,18 +105,17 @@ func (mh MngtHandler) WssocketHandler(w http.ResponseWriter, r *http.Request) { endpoints, _ := mh.service.ListEndpoints() bytes, err := json.Marshal(endpoints) if err != nil { - log.Fatal(err) + logger.LogError(errors.Errorf("ngonx mngt: ws :%v", err).Error()) } err = c.WriteMessage(mt, bytes) if err != nil { - log.Println("write endpoints:", err) - + logger.LogError(errors.Errorf("ngonx mngt: write endpoints ws :%v", err).Error()) } durations, err := time.ParseDuration(ds) if err != nil { err = c.WriteMessage(mt, []byte(err.Error())) if err != nil { - log.Println("write durations:", err) + logger.LogError(errors.Errorf("ngonx mngt: write durations ws :%v", err).Error()) } } time.Sleep(durations) @@ -124,7 +124,7 @@ func (mh MngtHandler) WssocketHandler(w http.ResponseWriter, r *http.Request) { default: err = c.WriteMessage(mt, []byte("CMD not found")) if err != nil { - log.Println("write default:", err) + logger.LogError(errors.Errorf("ngonx mngt: write default ws :%v", err).Error()) } } } From 95f454b392b9a72a71989eec62e237477b17dc18 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 10:19:27 -0500 Subject: [PATCH 09/14] ref: change log format --- internal/proxy/domain/lb.go | 4 +-- internal/proxy/domain/proxyrepository.go | 36 +++++++++++------------- internal/proxy/handlers/lb.go | 5 ++-- internal/proxy/handlers/proxy.go | 25 ++++++++++------ 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/internal/proxy/domain/lb.go b/internal/proxy/domain/lb.go index 229b2e0..19db25e 100644 --- a/internal/proxy/domain/lb.go +++ b/internal/proxy/domain/lb.go @@ -96,7 +96,7 @@ func (s *ServerPool) HealthCheck() { if !alive { status = "down" } - logger.LogInfo(fmt.Sprintf("%s [%s]\n", b.URL, status)) + logger.LogInfo(fmt.Sprintf("lb: %s [%s]\n", b.URL, status)) } } @@ -105,7 +105,7 @@ func isBackendAlive(u *url.URL) bool { timeout := 2 * time.Second conn, err := net.DialTimeout("tcp", u.Host, timeout) if err != nil { - logger.LogError(errors.ErrIsBackendAlive.Error()) + logger.LogError(errors.Errorf("lb: %v", errors.ErrIsBackendAlive).Error()) return false } _ = conn.Close() diff --git a/internal/proxy/domain/proxyrepository.go b/internal/proxy/domain/proxyrepository.go index fddebe0..d28bfc6 100644 --- a/internal/proxy/domain/proxyrepository.go +++ b/internal/proxy/domain/proxyrepository.go @@ -2,8 +2,6 @@ package proxy import ( "context" - "fmt" - "os" badger "github.com/dgraph-io/badger/v3" "github.com/go-redis/redis/v8" @@ -41,39 +39,39 @@ func (r ProxyRepositoryStorage) SaveKEY(engine, key, apikey string) error { logger.LogError(errors.ErrSavekeyUpdateTX.Error()) return errors.ErrSavekeyUpdateTX } - logger.LogInfo("savekey: successful") + logger.LogInfo("proxy: savekey was successful") return nil }); err != nil { - logger.LogError(errors.ErrSavekeyUpdate.Error()) + return errors.ErrSavekeyUpdate } return nil case "redis": if _, err := r.clientRdb.HSet(context.TODO(), key, apikey).Result(); err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("proxy redis: %v", err).Error()) } // r.clientRdb.Expire(context.TODO(), key, 24*time.Hour) - case "local": - f, err := os.Create("./apikey") + // case "local": + // f, err := os.Create("./apikey") - if err != nil { - logger.LogError(errors.ErrSavekeyCreateLocal.Error()) - return errors.ErrSavekeyCreateLocal - } + // if err != nil { + // logger.LogError(errors.ErrSavekeyCreateLocal.Error()) + // return errors.ErrSavekeyCreateLocal + // } - // defer f.Close() + // // defer f.Close() - data := []byte(fmt.Sprintf("%s:%s", key, apikey)) + // data := []byte(fmt.Sprintf("%s:%s", key, apikey)) - _, err = f.Write(data) + // _, err = f.Write(data) - if err != nil { - logger.LogError(errors.ErrSavekeyWriteOnLocal.Error()) - return errors.ErrSavekeyWriteOnLocal - } - return nil + // if err != nil { + // logger.LogError(errors.ErrSavekeyWriteOnLocal.Error()) + // return errors.ErrSavekeyWriteOnLocal + // } + // return nil } return nil } diff --git a/internal/proxy/handlers/lb.go b/internal/proxy/handlers/lb.go index 3b5a1eb..38b5492 100644 --- a/internal/proxy/handlers/lb.go +++ b/internal/proxy/handlers/lb.go @@ -33,7 +33,7 @@ func GetRetryFromContext(r *http.Request) int { func Lbalancer(w http.ResponseWriter, r *http.Request) { attempts := GetAttemptsFromContext(r) if attempts > 3 { - logger.LogInfo(fmt.Sprintf("%s(%s) Max attempts reached, terminating\n", r.RemoteAddr, r.URL.Path)) + logger.LogInfo(fmt.Sprintf("lb: %s(%s) Max attempts reached, terminating\n", r.RemoteAddr, r.URL.Path)) http.Error(w, errors.ErrLBHttp.Error(), http.StatusServiceUnavailable) return } @@ -50,8 +50,7 @@ func Lbalancer(w http.ResponseWriter, r *http.Request) { func HealthCheck() { t := time.NewTicker(time.Minute * 1) for range t.C { - logger.LogInfo("Starting health check...") ServerPool.HealthCheck() - logger.LogInfo("Health check completed") + logger.LogInfo("lb: Health check completed") } } diff --git a/internal/proxy/handlers/proxy.go b/internal/proxy/handlers/proxy.go index b1f48fb..e82f761 100644 --- a/internal/proxy/handlers/proxy.go +++ b/internal/proxy/handlers/proxy.go @@ -41,9 +41,9 @@ type ProxyHandler struct { func (ph *ProxyHandler) SaveSecretKEY(engine, key, apikey string) { result, err := ph.Service.SaveSecretKEY(engine, key, apikey) if err != nil { - logger.LogInfo(result) + logger.LogError(errors.Errorf("proxy: SaveSecretKEY %v", err).Error()) } - logger.LogInfo(result) + logger.LogInfo("proxy: SaveSecretKEY" + result) } // ProxyGateway handler for management all request @@ -54,7 +54,8 @@ func (ph *ProxyHandler) ProxyGateway(endpoints domain.ProxyEndpoint, engine, key fmt.Sprintf("%s%s", endpoints.HostURI, endpoint.PathEndpoint), ) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("proxy: %v", err).Error()) + } if endpoint.PathProtected { proxy = httputil.NewSingleHostReverseProxy(target) @@ -130,21 +131,26 @@ func checkJWTSecretKeyFromRequest(req *http.Request, key string) error { hs := jwt.NewHS256([]byte(key)) now := time.Now() if !strings.HasPrefix(header, "Bearer ") { - logger.LogError(errors.ErrBearerTokenFormat.Error()) + logger.LogError(errors.Errorf("proxy: %v", errors.ErrBearerTokenFormat).Error()) + return errors.ErrBearerTokenFormat } + token := strings.Split(header, " ")[1] pl := JWTPayload{} expValidator := jwt.ExpirationTimeValidator(now) validatePayload := jwt.ValidatePayload(&pl.Payload, expValidator) + _, err := jwt.Verify([]byte(token), hs, &pl, validatePayload) if errors.ErrorIs(err, jwt.ErrExpValidation) { - logger.LogError(errors.ErrTokenExpValidation.Error()) + logger.LogError(errors.Errorf("proxy: %v", errors.ErrTokenExpValidation).Error()) + return errors.ErrTokenExpValidation } if errors.ErrorIs(err, jwt.ErrHMACVerification) { - logger.LogError(errors.ErrTokenHMACValidation.Error()) + logger.LogError(errors.Errorf("proxy: %v", errors.ErrTokenHMACValidation).Error()) + return errors.ErrTokenHMACValidation } @@ -156,13 +162,14 @@ func checkAPIKEYSecretKeyFromRequest(req *http.Request, ph *ProxyHandler, engine apikey, err := ph.Service.GetKEY(engine, key) header := req.Header.Get("X-API-KEY") // pass to constants if err != nil { - logger.LogError(errors.ErrGetkeyView.Error()) + logger.LogError(errors.Errorf("proxy: %v", errors.ErrGetkeyView).Error()) + } if apikey == header { - logger.LogInfo("OK") + logger.LogInfo("proxy: check secret from request OK") return nil } else { - logger.LogInfo("Invalid apikey") + logger.LogError(errors.Errorf("proxy: Invalid API KEY").Error()) return errors.NewError("Invalid API KEY") } } From b993fd1dfd82c55a5c32d0ce0cb5d519c26b3558 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 10:30:00 -0500 Subject: [PATCH 10/14] ref: change log format --- pkg/badgerdb/client.go | 3 ++- pkg/config/config.go | 6 ++++-- pkg/genkey/genkey.go | 3 ++- pkg/healthcheck/health.go | 3 ++- pkg/httpsrv/server.go | 26 +++++++++++--------------- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/pkg/badgerdb/client.go b/pkg/badgerdb/client.go index 9789acb..fc9ccfc 100644 --- a/pkg/badgerdb/client.go +++ b/pkg/badgerdb/client.go @@ -2,6 +2,7 @@ package badgerdb import ( badger "github.com/dgraph-io/badger/v3" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" ) @@ -20,7 +21,7 @@ func GetBadgerDB(embedMem bool) *badger.DB { db, err := badger.Open(opt) if err != nil { - logger.LogError(err.Error()) + logger.LogError(errors.Errorf("badger: %v", err).Error()) panic(err) } diff --git a/pkg/config/config.go b/pkg/config/config.go index d16c065..36b8608 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -140,7 +140,8 @@ proxy: path_protected: true ` if err != nil { - logger.LogError(errors.ErrCreatingSettingFile.Error()) + logger.LogError(errors.Errorf("config: %v", errors.ErrCreatingSettingFile).Error()) + } // defer f.Close() @@ -150,6 +151,7 @@ proxy: _, err = f.Write(data) if err != nil { - logger.LogError(errors.ErrWritingSettingFile.Error()) + logger.LogError(errors.Errorf("config: %v", errors.ErrWritingSettingFile).Error()) + } } diff --git a/pkg/genkey/genkey.go b/pkg/genkey/genkey.go index d7df160..211a331 100644 --- a/pkg/genkey/genkey.go +++ b/pkg/genkey/genkey.go @@ -33,7 +33,8 @@ func ApiKeyGenerator(word string) string { h := sha256.New() _, err := h.Write([]byte(word)) if err != nil { - logger.LogError(errors.ErrApiKeyGenerator.Error()) + logger.LogError(errors.Errorf("genkeypkg: %v", errors.ErrApiKeyGenerator).Error()) + } return fmt.Sprintf("%x", h.Sum(nil)) } diff --git a/pkg/healthcheck/health.go b/pkg/healthcheck/health.go index a7032f0..4912d0e 100644 --- a/pkg/healthcheck/health.go +++ b/pkg/healthcheck/health.go @@ -14,7 +14,8 @@ func IsBackendAlive(u *url.URL) bool { timeout := 2 * time.Second conn, err := net.DialTimeout("tcp", u.Host, timeout) if err != nil { - logger.LogError(errors.ErrIsBackendAlive.Error()) + logger.LogError(errors.Errorf("healtcheck: %v", errors.ErrIsBackendAlive).Error()) + return false } _ = conn.Close() diff --git a/pkg/httpsrv/server.go b/pkg/httpsrv/server.go index 897473b..43e7cfd 100644 --- a/pkg/httpsrv/server.go +++ b/pkg/httpsrv/server.go @@ -9,6 +9,7 @@ import ( "os/signal" "time" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" ) @@ -57,31 +58,27 @@ func NewServerSSL(host string, port int, mux http.Handler) *server { // Start runs ListenAndServe on the http.Server with graceful shutdown func (srv *server) Start() { - logger.LogInfo("starting server...") + logger.LogInfo("ngonx: starting server...") go func() { if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - logger.LogError( - fmt.Sprintf("could not listen on %s due to %s", srv.Addr, err.Error()), - ) + logger.LogError(errors.Errorf("could not listen on %s due to %s", srv.Addr, err).Error()) } }() - logger.LogInfo(fmt.Sprintf("server is ready to handle requests %s", srv.Addr)) + logger.LogInfo(fmt.Sprintf("ngonx: server is ready to handle requests %s", srv.Addr)) srv.gracefulShutdown() } // Start runs ListenAndServe on the http.Server with graceful shutdown func (srv *server) StartSSL(crt, key string) { - logger.LogInfo("starting server...") + logger.LogInfo("ngonx: starting server...") go func() { if err := srv.ListenAndServeTLS(crt, key); err != nil && err != http.ErrServerClosed { - logger.LogError( - fmt.Sprintf("could not listen on %s due to %s", srv.Addr, err.Error()), - ) + logger.LogError(errors.Errorf("could not listen on %s due to %s", srv.Addr, err).Error()) } }() - logger.LogInfo(fmt.Sprintf("server is ready to handle requests %s", srv.Addr)) + logger.LogInfo(fmt.Sprintf("ngonx: server is ready to handle requests %s", srv.Addr)) srv.gracefulShutdown() } @@ -90,16 +87,15 @@ func (srv *server) gracefulShutdown() { signal.Notify(quit, os.Interrupt) sig := <-quit - logger.LogInfo(fmt.Sprintf("server is shutting down %s", sig.String())) + logger.LogInfo(fmt.Sprintf("ngonx: server is shutting down %s", sig.String())) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() srv.SetKeepAlivesEnabled(false) if err := srv.Shutdown(ctx); err != nil { - logger.LogError( - fmt.Sprintf("could not gracefully shutdown the server %s", err.Error()), - ) + logger.LogError(errors.Errorf("could not gracefully shutdown the server %s", err).Error()) + } - logger.LogInfo("server stopped") + logger.LogInfo("ngonx: server stopped") } From cc03fdba8fd7bc8baa40818ebe236a5b8c9ebf65 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 10:30:18 -0500 Subject: [PATCH 11/14] ref: add singleton pattern to db connection --- pkg/redisdb/client.go | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/pkg/redisdb/client.go b/pkg/redisdb/client.go index c0d506a..93a1da9 100644 --- a/pkg/redisdb/client.go +++ b/pkg/redisdb/client.go @@ -2,27 +2,36 @@ package redisdb import ( "context" + "sync" "time" + "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" "github.com/go-redis/redis/v8" ) +//Used to execute client creation procedure only once. +var redisOnce sync.Once + func GetRedisDbClient(redisUri, redisPass string) *redis.Client { + var clientInstance *redis.Client + redisOnce.Do(func() { + client := redis.NewClient(&redis.Options{ + Addr: redisUri, // use default Addr + Password: redisPass, // no password set + DB: 0, + DialTimeout: 60 * time.Second, + ReadTimeout: 60 * time.Second, + WriteTimeout: 60 * time.Second, + }) - clientInstance := redis.NewClient(&redis.Options{ - Addr: redisUri, // use default Addr - Password: redisPass, // no password set - DB: 0, - DialTimeout: 60 * time.Second, - ReadTimeout: 60 * time.Second, - WriteTimeout: 60 * time.Second, - }) + _, err := clientInstance.Ping(context.TODO()).Result() + if err != nil { + logger.LogError(errors.Errorf("redis: %v", err).Error()) - _, err := clientInstance.Ping(context.TODO()).Result() - if err != nil { - logger.LogError(err.Error()) - } + } + clientInstance = client + }) return clientInstance } From f449cf4ae17054641bc9c740c33f9798b7755b3a Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 10:40:28 -0500 Subject: [PATCH 12/14] docs: change ports --- scripts/request/micro-a.rest | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/request/micro-a.rest b/scripts/request/micro-a.rest index 118a3d1..a83b466 100644 --- a/scripts/request/micro-a.rest +++ b/scripts/request/micro-a.rest @@ -9,7 +9,7 @@ GET http://localhost:3001/api/v1/version/ ### Gateway Proxy -GET http://localhost:8080/version/ +GET http://localhost:35000/health/ ### GET https://localhost:30443/health/ @@ -21,12 +21,12 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJCYW5rIiwic ### Proxy -GET http://localhost:30000/version/ +GET http://localhost:35000/version/ Authorization: Bearerx eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJCYW5rIiwic3ViIjoiU3lzdGVtQXBwIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDAwIiwiZXhwIjoxNjI0ODk3ODQ4LCJuYmYiOjE2MjQ4OTkwNDgsImlhdCI6MTYyNDg5NzI0OCwianRpIjoiYXV0aC1zZXJ2ZXItMSIsIlVzZXJuYW1lIjoiTUFkbWluIiwiUm9sZSI6IkFETUlOIn0.TJn1Luy6jFsuRiQN0fAJYYQTxYWnO1wgWAUTGThY1Gg ### -GET http://localhost:30000/version/ +GET http://localhost:35000/version/ X-API-KEY: 6d5cdc4a5e51f11da6561b8e02bcbe3e4979066c7f9e71e780f15e23dd0f34ee ### SSL From 1779b2acc3e9020c61ccadfb3cbd65194ec5441b Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 11:23:14 -0500 Subject: [PATCH 13/14] ref: add caller tag to logger result --- pkg/logger/logger.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 11f0aae..5ee2779 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -9,11 +9,14 @@ import ( var log *zap.Logger func init() { - + config := zap.NewProductionConfig() encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.TimeKey = "timestamp" + encoderConfig.CallerKey = "caller" encoderConfig.StacktraceKey = "" encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder + config.EncoderConfig = encoderConfig w := zapcore.AddSync(&lumberjack.Logger{ Filename: "./ngonx-log/ngonx.log", @@ -21,13 +24,13 @@ func init() { MaxBackups: 3, MaxAge: 28, // days }) + core := zapcore.NewCore( - zapcore.NewConsoleEncoder(encoderConfig), + zapcore.NewConsoleEncoder(config.EncoderConfig), w, zap.InfoLevel, ) - log = zap.New(core) - + log = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) } // LogInfo wrap for log.info From 465b417795bc1b3bcf69166ca1f8a0ef7cd7b6c7 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Thu, 11 Nov 2021 11:37:21 -0500 Subject: [PATCH 14/14] ref: add var env validations --- pkg/logger/logger.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 5ee2779..efd23bb 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -1,11 +1,20 @@ package logger import ( + "os" + "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) +func GetEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} + var log *zap.Logger func init() { @@ -19,7 +28,7 @@ func init() { config.EncoderConfig = encoderConfig w := zapcore.AddSync(&lumberjack.Logger{ - Filename: "./ngonx-log/ngonx.log", + Filename: GetEnv(os.Getenv("NGONX_LOGS"), "./ngonx-log/ngonx.log"), MaxSize: 500, // megabytes MaxBackups: 3, MaxAge: 28, // days