// Copyright 2014 Manu Martinez-Almeida. All rights reserved. // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. package engines //type consoleColorModeValue int // //const ( // autoColor consoleColorModeValue = iota // disableColor // forceColor //) // const ( //green = "\033[97;42m" //white = "\033[90;47m" //yellow = "\033[90;43m" //red = "\033[97;41m" //blue = "\033[97;44m" //magenta = "\033[97;45m" //cyan = "\033[97;46m" reset = "\033[0m" ) // //var consoleColorMode = autoColor // LoggerConfig defines the config for Logger middleware. //type LoggerConfig struct { // // Optional. Default value is gin.defaultLogFormatter // Formatter LogFormatter // // // Output is a writer where logs are written. // // Optional. Default value is gin.DefaultWriter. // Output io.Writer // // // SkipPaths is a url path array which logs are not written. // // Optional. // SkipPaths []string //} // //// LogFormatter gives the signature of the formatter function passed to LoggerWithFormatter //type LogFormatter func(params LogFormatterParams) string // //// LogFormatterParams is the structure any formatter will be handed when time to log comes //type LogFormatterParams struct { // Request *http.Request // // // TimeStamp shows the time after the server returns a response. // TimeStamp time.Time // // StatusCode is HTTP response code. // StatusCode int // // Latency is how much time the server cost to process a certain request. // Latency time.Duration // // ClientIP equals Context's ClientIP method. // ClientIP string // // Method is the HTTP method given to the request. // Method string // // Path is a path the client requests. // Path string // // ErrorMessage is set if error has occurred in processing the request. // ErrorMessage string // // isTerm shows whether does gin's output descriptor refers to a terminal. // isTerm bool // // BodySize is the size of the Response Body // BodySize int // // Keys are the keys set on the request's context. // Keys map[string]interface{} //} // //// StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal. //func (p *LogFormatterParams) StatusCodeColor() string { // code := p.StatusCode // // switch { // case code >= http.StatusOK && code < http.StatusMultipleChoices: // return green // case code >= http.StatusMultipleChoices && code < http.StatusBadRequest: // return white // case code >= http.StatusBadRequest && code < http.StatusInternalServerError: // return yellow // default: // return red // } //} // //// MethodColor is the ANSI color for appropriately logging http method to a terminal. //func (p *LogFormatterParams) MethodColor() string { // method := p.Method // // switch method { // case "GET": // return blue // case "POST": // return cyan // case "PUT": // return yellow // case "DELETE": // return red // case "PATCH": // return green // case "HEAD": // return magenta // case "OPTIONS": // return white // default: // return reset // } //} // //// ResetColor resets all escape attributes. //func (p *LogFormatterParams) ResetColor() string { // return reset //} // //// IsOutputColor indicates whether can colors be outputted to the log. //func (p *LogFormatterParams) IsOutputColor() bool { // return consoleColorMode == forceColor || (consoleColorMode == autoColor && p.isTerm) //} // //// defaultLogFormatter is the default log format function Logger middleware uses. //var defaultLogFormatter = func(param LogFormatterParams) string { // var statusColor, methodColor, resetColor string // if param.IsOutputColor() { // statusColor = param.StatusCodeColor() // methodColor = param.MethodColor() // resetColor = param.ResetColor() // } // // if param.Latency > time.Minute { // // Truncate in a golang < 1.8 safe way // param.Latency = param.Latency - param.Latency%time.Second // } // return fmt.Sprintf("[GAUSS] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s", // param.TimeStamp.Format("2006/01/02 - 15:04:05"), // statusColor, param.StatusCode, resetColor, // param.Latency, // param.ClientIP, // methodColor, param.Method, resetColor, // param.Path, // param.ErrorMessage, // ) //} // //// DisableConsoleColor disables color output in the console. //func DisableConsoleColor() { // consoleColorMode = disableColor //} // //// ForceConsoleColor force color output in the console. //func ForceConsoleColor() { // consoleColorMode = forceColor //} // //// ErrorLogger returns a handlerfunc for any error type. //func ErrorLogger() HandlerFunc { // return ErrorLoggerT(ErrorTypeAny) //} // //// ErrorLoggerT returns a handlerfunc for a given error type. //func ErrorLoggerT(typ ErrorType) HandlerFunc { // return func(c *Context) { // c.Next() // errors := c.Errors.ByType(typ) // if len(errors) > 0 { // c.JSON(-1, errors) // } // } //} // //// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter. //// By default gin.DefaultWriter = os.Stdout. ////func Logger() HandlerFunc { //// return LoggerWithConfig(LoggerConfig{}) ////} // //// LoggerWithFormatter instance a Logger middleware with the specified log format function. //func LoggerWithFormatter(f LogFormatter) HandlerFunc { // return LoggerWithConfig(LoggerConfig{ // Formatter: f, // }) //} // //// LoggerWithWriter instance a Logger middleware with the specified writer buffer. //// Example: os.Stdout, a file opened in write mode, a socket... //func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc { // return LoggerWithConfig(LoggerConfig{ // Output: out, // SkipPaths: notlogged, // }) //} // //// LoggerWithConfig instance a Logger middleware with config. //func LoggerWithConfig(conf LoggerConfig) HandlerFunc { // formatter := conf.Formatter // if formatter == nil { // formatter = defaultLogFormatter // } // // out := conf.Output // if out == nil { // out = DefaultWriter // } // // notlogged := conf.SkipPaths // // isTerm := true // // if w, ok := out.(*os.File); !ok || os.Getenv("TERM") == "dumb" || // (!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd())) { // isTerm = false // } // // var skip map[string]struct{} // // if length := len(notlogged); length > 0 { // skip = make(map[string]struct{}, length) // // for _, path := range notlogged { // skip[path] = struct{}{} // } // } // // return func(c *Context) { // // Start timer // start := time.Now() // path := c.Request.URL.Path // raw := c.Request.URL.RawQuery // // // Process request // c.Next() // // // Log only when path is not being skipped // if _, ok := skip[path]; !ok { // param := LogFormatterParams{ // Request: c.Request, // isTerm: isTerm, // Keys: c.Keys, // } // // // Stop timer // param.TimeStamp = time.Now() // param.Latency = param.TimeStamp.Sub(start) // // param.ClientIP = c.ClientIP() // param.Method = c.Request.Method // param.StatusCode = c.Writer.Status() // param.ErrorMessage = c.Errors.ByType(ErrorTypePrivate).String() // // param.BodySize = c.Writer.Size() // // if raw != "" { // path = path + "?" + raw // } // // param.Path = path // // fmt.Fprint(out, formatter(param)) // } // } //}