6
6
"net/http"
7
7
"time"
8
8
9
- "github.com/gin-gonic/contrib/ginrus"
10
9
"github.com/sirupsen/logrus"
11
10
12
11
"github.com/gin-gonic/gin"
@@ -27,6 +26,63 @@ type Handler struct {
27
26
// DoNotPrivateKeyChecking is used for testing
28
27
var DoNotPrivateKeyChecking = false
29
28
29
+ type loggerEntryWithFields interface {
30
+ WithFields (fields logrus.Fields ) * logrus.Entry
31
+ }
32
+
33
+ // Ginrus returns a gin.HandlerFunc (middleware) that logs requests using logrus.
34
+ //
35
+ // Requests with errors are logged using logrus.Error().
36
+ // Requests without errors are logged using logrus.Info().
37
+ //
38
+ // It receives:
39
+ // 1. A time package format string (e.g. time.RFC3339).
40
+ // 2. A boolean stating whether to use UTC time zone or local.
41
+ // 3. Optionally, a list of paths to skip logging for (this is why
42
+ // we are not using upstream github.com/gin-gonic/contrib/ginrus)
43
+ func Ginrus (logger loggerEntryWithFields , timeFormat string , utc bool , notlogged ... string ) gin.HandlerFunc {
44
+ var skip map [string ]struct {}
45
+ if length := len (notlogged ); length > 0 {
46
+ skip = make (map [string ]struct {}, length )
47
+ for _ , path := range notlogged {
48
+ skip [path ] = struct {}{}
49
+ }
50
+ }
51
+
52
+ return func (c * gin.Context ) {
53
+ start := time .Now ()
54
+ // some evil middlewares modify this values
55
+ path := c .Request .URL .Path
56
+ c .Next ()
57
+
58
+ // log only when path is not being skipped
59
+ if _ , ok := skip [path ]; ! ok {
60
+ end := time .Now ()
61
+ latency := end .Sub (start )
62
+ if utc {
63
+ end = end .UTC ()
64
+ }
65
+
66
+ entry := logger .WithFields (logrus.Fields {
67
+ "status" : c .Writer .Status (),
68
+ "method" : c .Request .Method ,
69
+ "path" : path ,
70
+ "ip" : c .ClientIP (),
71
+ "latency" : latency ,
72
+ "user-agent" : c .Request .UserAgent (),
73
+ "time" : end .Format (timeFormat ),
74
+ })
75
+
76
+ if len (c .Errors ) > 0 {
77
+ // Append error field if this is an erroneous request.
78
+ entry .Error (c .Errors .String ())
79
+ } else {
80
+ entry .Info ()
81
+ }
82
+ }
83
+ }
84
+ }
85
+
30
86
// New initializes the http handlers
31
87
func New (store stores.Store ) (* Handler , error ) {
32
88
if ! util .GetConfig ().EnableDebugMode {
@@ -78,7 +134,12 @@ func (h *Handler) setHandlers() error {
78
134
if err := h .addTemplatesFromFS ([]string {"token.html" , "protected.html" }); err != nil {
79
135
return errors .Wrap (err , "could not add templates from FS" )
80
136
}
81
- h .engine .Use (ginrus .Ginrus (logrus .StandardLogger (), time .RFC3339 , false ))
137
+ if ! util .GetConfig ().EnableDebugMode {
138
+ // if we are not in debug mode, do not log healthchecks
139
+ h .engine .Use (Ginrus (logrus .StandardLogger (), time .RFC3339 , false , "/ok" ))
140
+ } else {
141
+ h .engine .Use (Ginrus (logrus .StandardLogger (), time .RFC3339 , false ))
142
+ }
82
143
protected := h .engine .Group ("/api/v1/protected" )
83
144
if util .GetConfig ().AuthBackend == "oauth" {
84
145
logrus .Info ("Using OAuth auth backend" )
@@ -96,6 +157,7 @@ func (h *Handler) setHandlers() error {
96
157
97
158
h .engine .GET ("/api/v1/info" , h .handleInfo )
98
159
h .engine .GET ("/d/:id/:hash" , h .handleDelete )
160
+ h .engine .GET ("/ok" , h .handleHealthcheck )
99
161
100
162
// Handling the shorted URLs, if no one exists, it checks
101
163
// in the filesystem and sets headers for caching
0 commit comments