Passed
Push — main ( 8298b6...aafc79 )
by Yume
01:56 queued 45s
created

http.loggerMiddleware   A

Complexity

Conditions 5

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nop 0
dl 0
loc 25
rs 9.1333
c 0
b 0
f 0
1
package http
2
3
import (
4
	"time"
5
6
	"github.com/ansrivas/fiberprometheus/v2"
7
	"github.com/gofiber/contrib/fibernewrelic"
8
	"github.com/gofiber/fiber/v2"
9
	"github.com/gofiber/fiber/v2/middleware/cache"
10
	"github.com/gofiber/fiber/v2/middleware/cors"
11
	"github.com/gofiber/fiber/v2/middleware/favicon"
12
	"github.com/gofiber/fiber/v2/middleware/pprof"
13
	"github.com/gofiber/swagger"
14
	influxdb2 "github.com/influxdata/influxdb-client-go/v2"
15
	"github.com/memnix/memnix-rest/app/misc"
16
	"github.com/memnix/memnix-rest/config"
17
	_ "github.com/memnix/memnix-rest/docs" // Side effect import
18
	"github.com/memnix/memnix-rest/infrastructures"
19
	"github.com/rs/zerolog/log"
20
)
21
22
// New returns a new Fiber instance
23
func New() *fiber.App {
24
	// Create new app
25
26
	app := fiber.New(
27
		fiber.Config{
28
			Prefork:     false,
29
			JSONDecoder: config.JSONHelper.Unmarshal,
30
			JSONEncoder: config.JSONHelper.Marshal,
31
		})
32
33
	// Register middlewares
34
	registerMiddlewares(app)
35
36
	app.Get("/", func(c *fiber.Ctx) error {
37
		return c.SendString("Hello, World 👋!")
38
	})
39
40
	// Use swagger middleware
41
	app.Get("/swagger/*", swagger.HandlerDefault) // default
42
43
	// Api group
44
	v2 := app.Group("/v2")
45
46
	v2.Get("/", func(c *fiber.Ctx) error {
47
		return fiber.NewError(fiber.StatusForbidden, "This is not a valid route") // Custom error
48
	})
49
50
	registerRoutes(&v2) // /v2
51
52
	return app
53
}
54
55
func registerMiddlewares(app *fiber.App) {
56
	// Use cors middleware
57
	app.Use(cors.New(cors.Config{
58
		AllowOrigins:     "http://localhost, *",
59
		AllowHeaders:     "Origin, Content-Type, Accept, Authorization, Cache-Control",
60
		AllowCredentials: true,
61
	}))
62
63
	// Provide a minimal config
64
	app.Use(favicon.New(favicon.Config{
65
		File: "./favicon.ico",
66
		URL:  "/favicon.ico",
67
	}))
68
69
	app.Use(cache.New(cache.Config{
70
		Expiration:   5 * time.Second,
71
		CacheControl: true,
72
		Next: func(c *fiber.Ctx) bool {
73
			// Do not cache /metrics endpoint
74
			return c.Path() == "/metrics"
75
		},
76
	}))
77
78
	cfg := fibernewrelic.Config{
79
		Application: infrastructures.GetRelicApp(),
80
	}
81
82
	app.Use(fibernewrelic.New(cfg))
83
84
	prometheus := fiberprometheus.New("memnix")
85
	prometheus.RegisterAt(app, "/metrics")
86
	app.Use(prometheus.Middleware)
87
88
	app.Use(pprof.New())
89
90
	app.Use(loggerMiddleware())
91
}
92
93
func loggerMiddleware() fiber.Handler {
94
	return func(c *fiber.Ctx) error {
95
		// Continue stack
96
		chainErr := c.Next()
97
98
		if chainErr != nil {
99
			if err := c.App().ErrorHandler(c, chainErr); err != nil {
100
				_ = c.SendStatus(fiber.StatusInternalServerError) //nolint:errcheck // TODO: Explain why we ignore the error here
101
			}
102
		}
103
104
		// Do something with response
105
		p := influxdb2.NewPointWithMeasurement("fiber").
106
			AddField("ip", c.IP()).
107
			AddField("method", c.Method()).
108
			AddField("path", c.Path()).
109
			AddField("status", c.Response().StatusCode()).
110
			SetTime(time.Now())
111
112
		_, err := misc.LogWriter{}.Write(*p)
113
		if err != nil {
114
			log.Error().Err(err).Msg("Error writing to influxdb")
115
		}
116
117
		return nil
118
	}
119
}
120