高热共公日志库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.4 KiB

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