github.com/eframework-cn/EP.GO.UTIL@v1.0.0/xlog/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 xlog
    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) {
    34  	lg.Lock()
    35  	h, _, _ := formatTimeHeader(when)
    36  	lg.writer.Write(append(append(h, msg...), '\n'))
    37  	lg.Unlock()
    38  }
    39  
    40  const (
    41  	y1  = `0123456789`
    42  	y2  = `0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789`
    43  	y3  = `0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999`
    44  	y4  = `0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789`
    45  	mo1 = `000000000111`
    46  	mo2 = `123456789012`
    47  	d1  = `0000000001111111111222222222233`
    48  	d2  = `1234567890123456789012345678901`
    49  	h1  = `000000000011111111112222`
    50  	h2  = `012345678901234567890123`
    51  	mi1 = `000000000011111111112222222222333333333344444444445555555555`
    52  	mi2 = `012345678901234567890123456789012345678901234567890123456789`
    53  	s1  = `000000000011111111112222222222333333333344444444445555555555`
    54  	s2  = `012345678901234567890123456789012345678901234567890123456789`
    55  	ns1 = `0123456789`
    56  )
    57  
    58  func formatTimeHeader(when time.Time) ([]byte, int, int) {
    59  	y, mo, d := when.Date()
    60  	h, mi, s := when.Clock()
    61  	ns := when.Nanosecond() / 1000000
    62  	//len("2006/01/02 15:04:05.123 ")==24
    63  	var buf [24]byte
    64  
    65  	buf[0] = y1[y/1000%10]
    66  	buf[1] = y2[y/100]
    67  	buf[2] = y3[y-y/100*100]
    68  	buf[3] = y4[y-y/100*100]
    69  	buf[4] = '/'
    70  	buf[5] = mo1[mo-1]
    71  	buf[6] = mo2[mo-1]
    72  	buf[7] = '/'
    73  	buf[8] = d1[d-1]
    74  	buf[9] = d2[d-1]
    75  	buf[10] = ' '
    76  	buf[11] = h1[h]
    77  	buf[12] = h2[h]
    78  	buf[13] = ':'
    79  	buf[14] = mi1[mi]
    80  	buf[15] = mi2[mi]
    81  	buf[16] = ':'
    82  	buf[17] = s1[s]
    83  	buf[18] = s2[s]
    84  	buf[19] = '.'
    85  	buf[20] = ns1[ns/100]
    86  	buf[21] = ns1[ns%100/10]
    87  	buf[22] = ns1[ns%10]
    88  
    89  	buf[23] = ' '
    90  
    91  	return buf[0:], d, h
    92  }
    93  
    94  var (
    95  	green   = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
    96  	white   = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
    97  	yellow  = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
    98  	red     = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
    99  	blue    = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
   100  	magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
   101  	cyan    = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
   102  
   103  	w32Green   = string([]byte{27, 91, 52, 50, 109})
   104  	w32White   = string([]byte{27, 91, 52, 55, 109})
   105  	w32Yellow  = string([]byte{27, 91, 52, 51, 109})
   106  	w32Red     = string([]byte{27, 91, 52, 49, 109})
   107  	w32Blue    = string([]byte{27, 91, 52, 52, 109})
   108  	w32Magenta = string([]byte{27, 91, 52, 53, 109})
   109  	w32Cyan    = string([]byte{27, 91, 52, 54, 109})
   110  
   111  	reset = string([]byte{27, 91, 48, 109})
   112  )
   113  
   114  var once sync.Once
   115  var colorMap map[string]string
   116  
   117  func initColor() {
   118  	if runtime.GOOS == "windows" {
   119  		green = w32Green
   120  		white = w32White
   121  		yellow = w32Yellow
   122  		red = w32Red
   123  		blue = w32Blue
   124  		magenta = w32Magenta
   125  		cyan = w32Cyan
   126  	}
   127  	colorMap = map[string]string{
   128  		//by color
   129  		"green":  green,
   130  		"white":  white,
   131  		"yellow": yellow,
   132  		"red":    red,
   133  		//by method
   134  		"GET":     blue,
   135  		"POST":    cyan,
   136  		"PUT":     yellow,
   137  		"DELETE":  red,
   138  		"PATCH":   green,
   139  		"HEAD":    magenta,
   140  		"OPTIONS": white,
   141  	}
   142  }
   143  
   144  // ColorByStatus return color by http code
   145  // 2xx return Green
   146  // 3xx return White
   147  // 4xx return Yellow
   148  // 5xx return Red
   149  func ColorByStatus(code int) string {
   150  	once.Do(initColor)
   151  	switch {
   152  	case code >= 200 && code < 300:
   153  		return colorMap["green"]
   154  	case code >= 300 && code < 400:
   155  		return colorMap["white"]
   156  	case code >= 400 && code < 500:
   157  		return colorMap["yellow"]
   158  	default:
   159  		return colorMap["red"]
   160  	}
   161  }
   162  
   163  // ColorByMethod return color by http code
   164  func ColorByMethod(method string) string {
   165  	once.Do(initColor)
   166  	if c := colorMap[method]; c != "" {
   167  		return c
   168  	}
   169  	return reset
   170  }
   171  
   172  // ResetColor return reset color
   173  func ResetColor() string {
   174  	return reset
   175  }