github.com/astaxie/beego@v1.12.3/logs/logger.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package logs
    16  
    17  import (
    18  	"io"
    19  	"runtime"
    20  	"sync"
    21  	"time"
    22  )
    23  
    24  type logWriter struct {
    25  	sync.Mutex
    26  	writer io.Writer
    27  }
    28  
    29  func newLogWriter(wr io.Writer) *logWriter {
    30  	return &logWriter{writer: wr}
    31  }
    32  
    33  func (lg *logWriter) writeln(when time.Time, msg string) (int, error) {
    34  	lg.Lock()
    35  	h, _, _ := formatTimeHeader(when)
    36  	n, err := lg.writer.Write(append(append(h, msg...), '\n'))
    37  	lg.Unlock()
    38  	return n, err
    39  }
    40  
    41  const (
    42  	y1  = `0123456789`
    43  	y2  = `0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789`
    44  	y3  = `0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999`
    45  	y4  = `0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789`
    46  	mo1 = `000000000111`
    47  	mo2 = `123456789012`
    48  	d1  = `0000000001111111111222222222233`
    49  	d2  = `1234567890123456789012345678901`
    50  	h1  = `000000000011111111112222`
    51  	h2  = `012345678901234567890123`
    52  	mi1 = `000000000011111111112222222222333333333344444444445555555555`
    53  	mi2 = `012345678901234567890123456789012345678901234567890123456789`
    54  	s1  = `000000000011111111112222222222333333333344444444445555555555`
    55  	s2  = `012345678901234567890123456789012345678901234567890123456789`
    56  	ns1 = `0123456789`
    57  )
    58  
    59  func formatTimeHeader(when time.Time) ([]byte, int, int) {
    60  	y, mo, d := when.Date()
    61  	h, mi, s := when.Clock()
    62  	ns := when.Nanosecond() / 1000000
    63  	//len("2006/01/02 15:04:05.123 ")==24
    64  	var buf [24]byte
    65  
    66  	buf[0] = y1[y/1000%10]
    67  	buf[1] = y2[y/100]
    68  	buf[2] = y3[y-y/100*100]
    69  	buf[3] = y4[y-y/100*100]
    70  	buf[4] = '/'
    71  	buf[5] = mo1[mo-1]
    72  	buf[6] = mo2[mo-1]
    73  	buf[7] = '/'
    74  	buf[8] = d1[d-1]
    75  	buf[9] = d2[d-1]
    76  	buf[10] = ' '
    77  	buf[11] = h1[h]
    78  	buf[12] = h2[h]
    79  	buf[13] = ':'
    80  	buf[14] = mi1[mi]
    81  	buf[15] = mi2[mi]
    82  	buf[16] = ':'
    83  	buf[17] = s1[s]
    84  	buf[18] = s2[s]
    85  	buf[19] = '.'
    86  	buf[20] = ns1[ns/100]
    87  	buf[21] = ns1[ns%100/10]
    88  	buf[22] = ns1[ns%10]
    89  
    90  	buf[23] = ' '
    91  
    92  	return buf[0:], d, h
    93  }
    94  
    95  var (
    96  	green   = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
    97  	white   = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
    98  	yellow  = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
    99  	red     = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
   100  	blue    = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
   101  	magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
   102  	cyan    = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
   103  
   104  	w32Green   = string([]byte{27, 91, 52, 50, 109})
   105  	w32White   = string([]byte{27, 91, 52, 55, 109})
   106  	w32Yellow  = string([]byte{27, 91, 52, 51, 109})
   107  	w32Red     = string([]byte{27, 91, 52, 49, 109})
   108  	w32Blue    = string([]byte{27, 91, 52, 52, 109})
   109  	w32Magenta = string([]byte{27, 91, 52, 53, 109})
   110  	w32Cyan    = string([]byte{27, 91, 52, 54, 109})
   111  
   112  	reset = string([]byte{27, 91, 48, 109})
   113  )
   114  
   115  var once sync.Once
   116  var colorMap map[string]string
   117  
   118  func initColor() {
   119  	if runtime.GOOS == "windows" {
   120  		green = w32Green
   121  		white = w32White
   122  		yellow = w32Yellow
   123  		red = w32Red
   124  		blue = w32Blue
   125  		magenta = w32Magenta
   126  		cyan = w32Cyan
   127  	}
   128  	colorMap = map[string]string{
   129  		//by color
   130  		"green":  green,
   131  		"white":  white,
   132  		"yellow": yellow,
   133  		"red":    red,
   134  		//by method
   135  		"GET":     blue,
   136  		"POST":    cyan,
   137  		"PUT":     yellow,
   138  		"DELETE":  red,
   139  		"PATCH":   green,
   140  		"HEAD":    magenta,
   141  		"OPTIONS": white,
   142  	}
   143  }
   144  
   145  // ColorByStatus return color by http code
   146  // 2xx return Green
   147  // 3xx return White
   148  // 4xx return Yellow
   149  // 5xx return Red
   150  func ColorByStatus(code int) string {
   151  	once.Do(initColor)
   152  	switch {
   153  	case code >= 200 && code < 300:
   154  		return colorMap["green"]
   155  	case code >= 300 && code < 400:
   156  		return colorMap["white"]
   157  	case code >= 400 && code < 500:
   158  		return colorMap["yellow"]
   159  	default:
   160  		return colorMap["red"]
   161  	}
   162  }
   163  
   164  // ColorByMethod return color by http code
   165  func ColorByMethod(method string) string {
   166  	once.Do(initColor)
   167  	if c := colorMap[method]; c != "" {
   168  		return c
   169  	}
   170  	return reset
   171  }
   172  
   173  // ResetColor return reset color
   174  func ResetColor() string {
   175  	return reset
   176  }