Skip to content

Commit

Permalink
Prometheus, redone middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
Franco Ferraguti committed Oct 25, 2023
1 parent 9d732d3 commit ba51632
Show file tree
Hide file tree
Showing 11 changed files with 352 additions and 117 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@

# Data generated by Prometheus (I think?)
data/

# MacOS
.DS_Store
28 changes: 17 additions & 11 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (

"github.com/gilperopiola/go-rest-example/pkg/common/auth"
"github.com/gilperopiola/go-rest-example/pkg/common/config"
"github.com/gilperopiola/go-rest-example/pkg/common/metrics"
"github.com/gilperopiola/go-rest-example/pkg/common/middleware"
"github.com/gilperopiola/go-rest-example/pkg/repository"
"github.com/gilperopiola/go-rest-example/pkg/service"
"github.com/gilperopiola/go-rest-example/pkg/transport"
"github.com/gin-gonic/gin"
)

// TODO
Expand All @@ -34,17 +34,23 @@ func main() {
// Load configuration settings
config = config.New(".env")

// Init Prometheus metrics
metrics = metrics.New()

// Initialize logger
logger = middleware.NewLogger()

// Initialize middlewares: logger, monitoring, prometheus
middlewares = middleware.Middlewares{
LoggerToCtx: middleware.NewLoggerToContextMiddleware(logger),
Monitoring: middleware.NewMonitoringMiddleware(config.Monitoring),
Prometheus: middleware.NewPrometheusMiddleware(metrics),
// We use prometheus to get metrics
prometheus = middleware.NewPrometheus(logger)

// We use New Relic to monitor the app
newRelic = middleware.NewMonitoringNewRelic(config.Monitoring)

// Initialize middlewares
middlewares = []gin.HandlerFunc{
gin.Recovery(),
middleware.NewCORSConfigMiddleware(),
middleware.NewLoggerToContextMiddleware(logger),
middleware.NewNewRelicMiddleware(newRelic),
middleware.NewPrometheusMiddleware(prometheus),
middleware.NewTimeoutMiddleware(config.General.Timeout),
}

// Initialize authentication module
Expand All @@ -56,10 +62,10 @@ func main() {
// Initialize repository layer with the database connection
repository = repository.New(database)

// Setup the main service layer with dependencies
// Setup the main service layer
service = service.New(repository, auth, config)

// Setup endpoints & transport layer with dependencies
// Setup endpoints & transport layer
endpoints = transport.New(service, transport.NewErrorsMapper(logger))

// Initialize the router with the endpoints
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/kelseyhightower/envconfig v1.4.0
github.com/newrelic/go-agent/v3 v3.26.0
github.com/newrelic/go-agent/v3/integrations/nrgin v1.2.1
github.com/prometheus/client_golang v1.17.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
)
Expand All @@ -36,15 +37,13 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
Expand Down
4 changes: 1 addition & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down Expand Up @@ -136,8 +135,7 @@ github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwa
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
22 changes: 0 additions & 22 deletions pkg/common/metrics/metrics.go

This file was deleted.

17 changes: 17 additions & 0 deletions pkg/common/middleware/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package middleware

import "github.com/sirupsen/logrus"

type LoggerI interface {
Info(args ...interface{})
Warn(args ...interface{})
Error(args ...interface{})
Fatalf(format string, args ...interface{})
}

func NewLogger() LoggerI {
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})
logger.SetLevel(logrus.InfoLevel)
return logger
}
71 changes: 1 addition & 70 deletions pkg/common/middleware/middleware.go
Original file line number Diff line number Diff line change
@@ -1,83 +1,14 @@
package middleware

import (
"fmt"
"log"
"time"

"github.com/gilperopiola/go-rest-example/pkg/common/config"
"github.com/gilperopiola/go-rest-example/pkg/common/metrics"
"github.com/sirupsen/logrus"

"github.com/gin-contrib/cors"
"github.com/gin-contrib/timeout"
"github.com/gin-gonic/gin"
"github.com/newrelic/go-agent/v3/integrations/nrgin"
"github.com/newrelic/go-agent/v3/newrelic"
)

type LoggerI interface {
Info(args ...interface{})
Warn(args ...interface{})
Error(args ...interface{})
Fatalf(format string, args ...interface{})
}

func NewLogger() LoggerI {
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})
logger.SetLevel(logrus.InfoLevel)
return logger
}

type Middlewares struct {
LoggerToCtx gin.HandlerFunc
Monitoring gin.HandlerFunc
Prometheus gin.HandlerFunc
}

func NewPrometheusMiddleware(metrics *metrics.Metrics) gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()

// Don't log calls to /metrics
if c.Request.URL.Path == "/metrics" {
return
}

// HTTP Response Status
status := fmt.Sprint(c.Writer.Status())

metrics.RequestsTotal.WithLabelValues(c.Request.Method, c.Request.URL.Path, status).Inc()
}
}

func NewMonitoringMiddleware(config config.Monitoring) gin.HandlerFunc {

// If monitoring is not enabled, return empty middleware
if !config.Enabled {
return gin.HandlerFunc(func(c *gin.Context) {})
}

// If monitoring is enabled, use license to create New Relic app
license := config.Secret
if license == "" {
log.Fatalf("New Relic license not found")
}

newRelicApp, err := newrelic.NewApplication(
newrelic.ConfigAppName(config.AppName),
newrelic.ConfigLicense(license),
newrelic.ConfigAppLogForwardingEnabled(true),
)

// Panic on failure
if err != nil {
log.Fatalf("Failed to start New Relic: %v", err)
}

return nrgin.Middleware(newRelicApp)
}
type Middlewares []gin.HandlerFunc

func NewTimeoutMiddleware(timeoutSeconds int) gin.HandlerFunc {
return timeout.New(
Expand Down
43 changes: 43 additions & 0 deletions pkg/common/middleware/new_relic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package middleware

import (
"log"

"github.com/gilperopiola/go-rest-example/pkg/common/config"
"github.com/gin-gonic/gin"

"github.com/newrelic/go-agent/v3/integrations/nrgin"
"github.com/newrelic/go-agent/v3/newrelic"
)

func NewNewRelicMiddleware(app *newrelic.Application) gin.HandlerFunc {
return nrgin.Middleware(app)
}

func NewMonitoringNewRelic(config config.Monitoring) *newrelic.Application {

// If monitoring is not enabled, return empty middleware
if !config.Enabled {
return nil
}

// If monitoring is enabled, use license to create New Relic app
license := config.Secret
if license == "" {
log.Fatalf("New Relic license not found")
}

// Create app
newRelicApp, err := newrelic.NewApplication(
newrelic.ConfigAppName(config.AppName),
newrelic.ConfigLicense(license),
newrelic.ConfigAppLogForwardingEnabled(true),
)

// Panic on failure
if err != nil {
log.Fatalf("Failed to start New Relic: %v", err)
}

return newRelicApp
}
Loading

0 comments on commit ba51632

Please sign in to comment.