OSDN Git Service

feat(warder): add warder backbone (#181)
[bytom/vapor.git] / vendor / github.com / gin-gonic / gin / logger.go
1 // Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
2 // Use of this source code is governed by a MIT style
3 // license that can be found in the LICENSE file.
4
5 package gin
6
7 import (
8         "fmt"
9         "io"
10         "net/http"
11         "os"
12         "time"
13
14         "github.com/mattn/go-isatty"
15 )
16
17 var (
18         green        = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
19         white        = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
20         yellow       = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
21         red          = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
22         blue         = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
23         magenta      = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
24         cyan         = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
25         reset        = string([]byte{27, 91, 48, 109})
26         disableColor = false
27 )
28
29 // DisableConsoleColor disables color output in the console.
30 func DisableConsoleColor() {
31         disableColor = true
32 }
33
34 // ErrorLogger returns a handlerfunc for any error type.
35 func ErrorLogger() HandlerFunc {
36         return ErrorLoggerT(ErrorTypeAny)
37 }
38
39 // ErrorLoggerT returns a handlerfunc for a given error type.
40 func ErrorLoggerT(typ ErrorType) HandlerFunc {
41         return func(c *Context) {
42                 c.Next()
43                 errors := c.Errors.ByType(typ)
44                 if len(errors) > 0 {
45                         c.JSON(-1, errors)
46                 }
47         }
48 }
49
50 // Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
51 // By default gin.DefaultWriter = os.Stdout.
52 func Logger() HandlerFunc {
53         return LoggerWithWriter(DefaultWriter)
54 }
55
56 // LoggerWithWriter instance a Logger middleware with the specified writter buffer.
57 // Example: os.Stdout, a file opened in write mode, a socket...
58 func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
59         isTerm := true
60
61         if w, ok := out.(*os.File); !ok ||
62                 (os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd()))) ||
63                 disableColor {
64                 isTerm = false
65         }
66
67         var skip map[string]struct{}
68
69         if length := len(notlogged); length > 0 {
70                 skip = make(map[string]struct{}, length)
71
72                 for _, path := range notlogged {
73                         skip[path] = struct{}{}
74                 }
75         }
76
77         return func(c *Context) {
78                 // Start timer
79                 start := time.Now()
80                 path := c.Request.URL.Path
81                 raw := c.Request.URL.RawQuery
82
83                 // Process request
84                 c.Next()
85
86                 // Log only when path is not being skipped
87                 if _, ok := skip[path]; !ok {
88                         // Stop timer
89                         end := time.Now()
90                         latency := end.Sub(start)
91
92                         clientIP := c.ClientIP()
93                         method := c.Request.Method
94                         statusCode := c.Writer.Status()
95                         var statusColor, methodColor, resetColor string
96                         if isTerm {
97                                 statusColor = colorForStatus(statusCode)
98                                 methodColor = colorForMethod(method)
99                                 resetColor = reset
100                         }
101                         comment := c.Errors.ByType(ErrorTypePrivate).String()
102
103                         if raw != "" {
104                                 path = path + "?" + raw
105                         }
106
107                         fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
108                                 end.Format("2006/01/02 - 15:04:05"),
109                                 statusColor, statusCode, resetColor,
110                                 latency,
111                                 clientIP,
112                                 methodColor, method, resetColor,
113                                 path,
114                                 comment,
115                         )
116                 }
117         }
118 }
119
120 func colorForStatus(code int) string {
121         switch {
122         case code >= http.StatusOK && code < http.StatusMultipleChoices:
123                 return green
124         case code >= http.StatusMultipleChoices && code < http.StatusBadRequest:
125                 return white
126         case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
127                 return yellow
128         default:
129                 return red
130         }
131 }
132
133 func colorForMethod(method string) string {
134         switch method {
135         case "GET":
136                 return blue
137         case "POST":
138                 return cyan
139         case "PUT":
140                 return yellow
141         case "DELETE":
142                 return red
143         case "PATCH":
144                 return green
145         case "HEAD":
146                 return magenta
147         case "OPTIONS":
148                 return white
149         default:
150                 return reset
151         }
152 }