Skip to content

Commit

Permalink
Refactor code: request/response logging middleware, entity, standard …
Browse files Browse the repository at this point in the history
…logging for troubleshooting
  • Loading branch information
james03160927 committed Jan 4, 2025
1 parent ef6aa27 commit 9adc363
Show file tree
Hide file tree
Showing 20 changed files with 215 additions and 197 deletions.
23 changes: 23 additions & 0 deletions common/string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package common

import (
"encoding/json"
"fmt"
)

func PrettifyJSON(input string) (string, error) {
// First unmarshal the input string into a generic interface{}
var temp interface{}
err := json.Unmarshal([]byte(input), &temp)
if err != nil {
return "", fmt.Errorf("invalid JSON input: %v", err)
}

// Marshal back to JSON with indentation
pretty, err := json.MarshalIndent(temp, "", " ")
if err != nil {
return "", fmt.Errorf("failed to marshal JSON: %v", err)
}

return string(pretty), nil
}
19 changes: 19 additions & 0 deletions entity/node.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package entity

import "registry-backend/ent"

// NodeFilter holds optional parameters for filtering node results
type NodeFilter struct {
PublisherID string
Search string
IncludeBanned bool
}

// ListNodesResult is the structure that holds the paginated result of nodes
type ListNodesResult struct {
Total int `json:"total"`
Nodes []*ent.Node `json:"nodes"`
Page int `json:"page"`
Limit int `json:"limit"`
TotalPages int `json:"totalPages"`
}
24 changes: 24 additions & 0 deletions entity/node_version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package entity

import (
"registry-backend/ent"
"registry-backend/ent/schema"
"time"
)

type NodeVersionFilter struct {
NodeId string
Status []schema.NodeVersionStatus
IncludeStatusReason bool
MinAge time.Duration
PageSize int
Page int
}

type ListNodeVersionsResult struct {
Total int `json:"total"`
NodeVersions []*ent.NodeVersion `json:"nodes"`
Page int `json:"page"`
Limit int `json:"limit"`
TotalPages int `json:"totalPages"`
}
5 changes: 5 additions & 0 deletions entity/publisher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package entity

type PublisherFilter struct {
UserID string
}
2 changes: 1 addition & 1 deletion common/types.go → entity/token.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// File: common/types.go

package common
package entity

type InviteTokenStatus string

Expand Down
65 changes: 11 additions & 54 deletions server/implementation/registry.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion server/middleware/authentication/firebase_auth.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_authentication
package authentication

import (
"context"
Expand Down
2 changes: 1 addition & 1 deletion server/middleware/authentication/firebase_auth_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_authentication
package authentication

import (
"net/http"
Expand Down
2 changes: 1 addition & 1 deletion server/middleware/authentication/jwt_admin_auth.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_authentication
package authentication

import (
"context"
Expand Down
2 changes: 1 addition & 1 deletion server/middleware/authentication/jwt_admin_auth_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_authentication
package authentication

import (
"net/http"
Expand Down
2 changes: 1 addition & 1 deletion server/middleware/authentication/service_account_auth.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_authentication
package authentication

import (
"net/http"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_authentication
package authentication

import (
"net/http"
Expand Down
24 changes: 0 additions & 24 deletions server/middleware/error_logger.go

This file was deleted.

2 changes: 1 addition & 1 deletion server/middleware/metric/metric.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_metric
package metric

import (
"context"
Expand Down
2 changes: 1 addition & 1 deletion server/middleware/metric/metric_middleware.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_metric
package metric

import (
"context"
Expand Down
38 changes: 38 additions & 0 deletions server/middleware/request_logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package middleware

import (
"bytes"
"fmt"
"github.com/labstack/echo/v4"
echo_middleware "github.com/labstack/echo/v4/middleware"
"github.com/rs/zerolog/log"
"io"
)

func RequestLoggerMiddleware() echo.MiddlewareFunc {
return echo_middleware.RequestLoggerWithConfig(echo_middleware.RequestLoggerConfig{
LogURI: true,
LogStatus: true,
LogValuesFunc: func(c echo.Context, v echo_middleware.RequestLoggerValues) error {
// Read the request body for logging
requestBody, err := io.ReadAll(c.Request().Body)
if err != nil {
log.Ctx(c.Request().Context()).Error().Err(err).Msg("Failed to read request body")
return err
}
// Reset the body for further use
c.Request().Body = io.NopCloser(bytes.NewReader(requestBody))

// Log request details including query parameters
log.Ctx(c.Request().Context()).
Info().
Str("Method", c.Request().Method).
Str("Path", c.Path()).
Str("QueryParams", fmt.Sprintf("%v", c.QueryParams())).
Str("RequestBody", string(requestBody)).
Str("Headers", fmt.Sprintf("%v", c.Request().Header)).
Msg("Request received")
return nil
},
})
}
63 changes: 63 additions & 0 deletions server/middleware/response_logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package middleware

import (
"bytes"
"fmt"
"net/http"

"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
)

// Custom response writer to capture response body
type responseWriter struct {
http.ResponseWriter
body *bytes.Buffer
}

func (rw *responseWriter) Write(p []byte) (n int, err error) {
// Capture the response body in the buffer
n, err = rw.body.Write(p)
if err != nil {
return n, err
}
// Write to the actual ResponseWriter
return rw.ResponseWriter.Write(p)
}

// ResponseLoggerMiddleware will log response details and errors.
func ResponseLoggerMiddleware() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// Create a custom response writer to capture the response body
rw := &responseWriter{
ResponseWriter: c.Response().Writer,
body: new(bytes.Buffer),
}
c.Response().Writer = rw

// Call the next handler in the chain
err := next(c)

// Log any errors that occur during handling
if err != nil {
log.Ctx(c.Request().Context()).
Error().
Err(err).
Str("Method", c.Request().Method).
Str("Path", c.Path()).
Msg("Error occurred during request handling")
}

// Log the response details
log.Ctx(c.Request().Context()).
Info().
Int("Status", c.Response().Status).
Str("ResponseBody", rw.body.String()).
Str("ResponseHeaders", fmt.Sprintf("%v", c.Response().Header())).
Msg("Response sent")

return err
}
}
}
2 changes: 1 addition & 1 deletion server/middleware/tracing_middleware.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package drip_middleware
package middleware

import (
"context"
Expand Down
57 changes: 14 additions & 43 deletions server/server.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package server

import (
monitoring "cloud.google.com/go/monitoring/apiv3/v2"
"context"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"registry-backend/config"
generated "registry-backend/drip"
"registry-backend/ent"
Expand All @@ -12,18 +15,10 @@ import (
"registry-backend/gateways/storage"
handler "registry-backend/server/handlers"
"registry-backend/server/implementation"
drip_middleware "registry-backend/server/middleware"
drip_authentication "registry-backend/server/middleware/authentication"
drip_authorization "registry-backend/server/middleware/authorization"
drip_metric "registry-backend/server/middleware/metric"
"strings"

monitoring "cloud.google.com/go/monitoring/apiv3/v2"

"github.com/labstack/echo/v4/middleware"
"github.com/rs/zerolog/log"

"github.com/labstack/echo/v4"
"registry-backend/server/middleware"
"registry-backend/server/middleware/authentication"
"registry-backend/server/middleware/authorization"
"registry-backend/server/middleware/metric"
)

type ServerDependencies struct {
Expand Down Expand Up @@ -97,30 +92,13 @@ func (s *Server) Start() error {
e.HideBanner = true

// Apply middleware
e.Use(drip_middleware.TracingMiddleware)
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{"*"},
AllowHeaders: []string{"*"},
AllowOriginFunc: func(origin string) (bool, error) {
return true, nil
},
AllowCredentials: true,
}))
e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
LogURI: true,
LogStatus: true,
LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
if strings.HasPrefix(c.Request().URL.Path, "/vm/") {
return nil
}

log.Ctx(c.Request().Context()).Debug().
Str("URI: ", v.URI).
Int("status", v.Status).Msg("")
return nil
},
}))
e.Use(middleware.TracingMiddleware)
e.Use(middleware.RequestLoggerMiddleware())
e.Use(middleware.ResponseLoggerMiddleware())
e.Use(metric.MetricsMiddleware(&s.Dependencies.MonitoringClient, s.Config))
e.Use(authentication.FirebaseAuthMiddleware(s.Client))
e.Use(authentication.ServiceAccountAuthMiddleware())
e.Use(authentication.JWTAdminAuthMiddleware(s.Client, s.Config.JWTSecret))

// Attach implementation of the generated OAPI strict server
impl := implementation.NewStrictServerImplementation(
Expand All @@ -144,13 +122,6 @@ func (s *Server) Start() error {
e.GET("/openapi", handler.SwaggerHandler)
e.GET("/health", s.HealthCheckHandler)

// Apply global middlewares
e.Use(drip_metric.MetricsMiddleware(&s.Dependencies.MonitoringClient, s.Config))
e.Use(drip_authentication.FirebaseAuthMiddleware(s.Client))
e.Use(drip_authentication.ServiceAccountAuthMiddleware())
e.Use(drip_authentication.JWTAdminAuthMiddleware(s.Client, s.Config.JWTSecret))
e.Use(drip_middleware.ErrorLoggingMiddleware())

// Start the server
return e.Start(":8080")
}
Expand Down
Loading

0 comments on commit 9adc363

Please sign in to comment.