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.

245 lines
7.5 KiB

Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
5 years ago
  1. // Copyright 2019 The Gitea Authors. 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. package log
  5. import (
  6. "compress/gzip"
  7. "fmt"
  8. "io/ioutil"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "testing"
  13. "time"
  14. "github.com/stretchr/testify/assert"
  15. )
  16. func TestFileLoggerFails(t *testing.T) {
  17. tmpDir, err := ioutil.TempDir("", "TestFileLogger")
  18. assert.NoError(t, err)
  19. defer os.RemoveAll(tmpDir)
  20. prefix := "TestPrefix "
  21. level := INFO
  22. flags := LstdFlags | LUTC | Lfuncname
  23. //filename := filepath.Join(tmpDir, "test.log")
  24. fileLogger := NewFileLogger()
  25. //realFileLogger, ok := fileLogger.(*FileLogger)
  26. //assert.Equal(t, true, ok)
  27. // Fail if there is bad json
  28. err = fileLogger.Init("{")
  29. assert.Error(t, err)
  30. // Fail if there is no filename
  31. err = fileLogger.Init(fmt.Sprintf("{\"prefix\":\"%s\",\"level\":\"%s\",\"flags\":%d,\"filename\":\"%s\"}", prefix, level.String(), flags, ""))
  32. assert.Error(t, err)
  33. // Fail if the file isn't a filename
  34. err = fileLogger.Init(fmt.Sprintf("{\"prefix\":\"%s\",\"level\":\"%s\",\"flags\":%d,\"filename\":\"%s\"}", prefix, level.String(), flags, filepath.ToSlash(tmpDir)))
  35. assert.Error(t, err)
  36. }
  37. func TestFileLogger(t *testing.T) {
  38. tmpDir, err := ioutil.TempDir("", "TestFileLogger")
  39. assert.NoError(t, err)
  40. defer os.RemoveAll(tmpDir)
  41. prefix := "TestPrefix "
  42. level := INFO
  43. flags := LstdFlags | LUTC | Lfuncname
  44. filename := filepath.Join(tmpDir, "test.log")
  45. fileLogger := NewFileLogger()
  46. realFileLogger, ok := fileLogger.(*FileLogger)
  47. assert.Equal(t, true, ok)
  48. location, _ := time.LoadLocation("EST")
  49. date := time.Date(2019, time.January, 13, 22, 3, 30, 15, location)
  50. dateString := date.UTC().Format("2006/01/02 15:04:05")
  51. event := Event{
  52. level: INFO,
  53. msg: "TEST MSG",
  54. caller: "CALLER",
  55. filename: "FULL/FILENAME",
  56. line: 1,
  57. time: date,
  58. }
  59. expected := fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  60. fileLogger.Init(fmt.Sprintf("{\"prefix\":\"%s\",\"level\":\"%s\",\"flags\":%d,\"filename\":\"%s\",\"maxsize\":%d,\"compress\":false}", prefix, level.String(), flags, filepath.ToSlash(filename), len(expected)*2))
  61. assert.Equal(t, flags, realFileLogger.Flags)
  62. assert.Equal(t, level, realFileLogger.Level)
  63. assert.Equal(t, level, fileLogger.GetLevel())
  64. fileLogger.LogEvent(&event)
  65. fileLogger.Flush()
  66. logData, err := ioutil.ReadFile(filename)
  67. assert.NoError(t, err)
  68. assert.Equal(t, expected, string(logData))
  69. event.level = DEBUG
  70. fileLogger.LogEvent(&event)
  71. fileLogger.Flush()
  72. logData, err = ioutil.ReadFile(filename)
  73. assert.NoError(t, err)
  74. assert.Equal(t, expected, string(logData))
  75. event.level = TRACE
  76. fileLogger.LogEvent(&event)
  77. fileLogger.Flush()
  78. logData, err = ioutil.ReadFile(filename)
  79. assert.NoError(t, err)
  80. assert.Equal(t, expected, string(logData))
  81. event.level = WARN
  82. expected = expected + fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  83. fileLogger.LogEvent(&event)
  84. fileLogger.Flush()
  85. logData, err = ioutil.ReadFile(filename)
  86. assert.NoError(t, err)
  87. assert.Equal(t, expected, string(logData))
  88. // Should rotate
  89. fileLogger.LogEvent(&event)
  90. fileLogger.Flush()
  91. logData, err = ioutil.ReadFile(filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1))
  92. assert.NoError(t, err)
  93. assert.Equal(t, expected, string(logData))
  94. logData, err = ioutil.ReadFile(filename)
  95. assert.NoError(t, err)
  96. expected = fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  97. assert.Equal(t, expected, string(logData))
  98. for num := 2; num <= 999; num++ {
  99. file, err := os.OpenFile(filename+fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num), os.O_RDONLY|os.O_CREATE, 0666)
  100. assert.NoError(t, err)
  101. file.Close()
  102. }
  103. err = realFileLogger.DoRotate()
  104. assert.Error(t, err)
  105. expected = expected + fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  106. fileLogger.LogEvent(&event)
  107. fileLogger.Flush()
  108. logData, err = ioutil.ReadFile(filename)
  109. assert.NoError(t, err)
  110. assert.Equal(t, expected, string(logData))
  111. // Should fail to rotate
  112. expected = expected + fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  113. fileLogger.LogEvent(&event)
  114. fileLogger.Flush()
  115. logData, err = ioutil.ReadFile(filename)
  116. assert.NoError(t, err)
  117. assert.Equal(t, expected, string(logData))
  118. fileLogger.Close()
  119. }
  120. func TestCompressFileLogger(t *testing.T) {
  121. tmpDir, err := ioutil.TempDir("", "TestFileLogger")
  122. assert.NoError(t, err)
  123. defer os.RemoveAll(tmpDir)
  124. prefix := "TestPrefix "
  125. level := INFO
  126. flags := LstdFlags | LUTC | Lfuncname
  127. filename := filepath.Join(tmpDir, "test.log")
  128. fileLogger := NewFileLogger()
  129. realFileLogger, ok := fileLogger.(*FileLogger)
  130. assert.Equal(t, true, ok)
  131. location, _ := time.LoadLocation("EST")
  132. date := time.Date(2019, time.January, 13, 22, 3, 30, 15, location)
  133. dateString := date.UTC().Format("2006/01/02 15:04:05")
  134. event := Event{
  135. level: INFO,
  136. msg: "TEST MSG",
  137. caller: "CALLER",
  138. filename: "FULL/FILENAME",
  139. line: 1,
  140. time: date,
  141. }
  142. expected := fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  143. fileLogger.Init(fmt.Sprintf("{\"prefix\":\"%s\",\"level\":\"%s\",\"flags\":%d,\"filename\":\"%s\",\"maxsize\":%d,\"compress\":true}", prefix, level.String(), flags, filepath.ToSlash(filename), len(expected)*2))
  144. fileLogger.LogEvent(&event)
  145. fileLogger.Flush()
  146. logData, err := ioutil.ReadFile(filename)
  147. assert.NoError(t, err)
  148. assert.Equal(t, expected, string(logData))
  149. event.level = WARN
  150. expected = expected + fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.filename, event.line, event.caller, strings.ToUpper(event.level.String())[0], event.msg)
  151. fileLogger.LogEvent(&event)
  152. fileLogger.Flush()
  153. logData, err = ioutil.ReadFile(filename)
  154. assert.NoError(t, err)
  155. assert.Equal(t, expected, string(logData))
  156. // Should rotate
  157. fileLogger.LogEvent(&event)
  158. fileLogger.Flush()
  159. for num := 2; num <= 999; num++ {
  160. file, err := os.OpenFile(filename+fmt.Sprintf(".%s.%03d.gz", time.Now().Format("2006-01-02"), num), os.O_RDONLY|os.O_CREATE, 0666)
  161. assert.NoError(t, err)
  162. file.Close()
  163. }
  164. err = realFileLogger.DoRotate()
  165. assert.Error(t, err)
  166. }
  167. func TestCompressOldFile(t *testing.T) {
  168. tmpDir, err := ioutil.TempDir("", "TestFileLogger")
  169. assert.NoError(t, err)
  170. defer os.RemoveAll(tmpDir)
  171. fname := filepath.Join(tmpDir, "test")
  172. nonGzip := filepath.Join(tmpDir, "test-nonGzip")
  173. f, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY, 0660)
  174. assert.NoError(t, err)
  175. ng, err := os.OpenFile(nonGzip, os.O_CREATE|os.O_WRONLY, 0660)
  176. assert.NoError(t, err)
  177. for i := 0; i < 999; i++ {
  178. f.WriteString("This is a test file\n")
  179. ng.WriteString("This is a test file\n")
  180. }
  181. f.Close()
  182. ng.Close()
  183. err = compressOldLogFile(fname, -1)
  184. assert.NoError(t, err)
  185. _, err = os.Lstat(fname + ".gz")
  186. assert.NoError(t, err)
  187. f, err = os.Open(fname + ".gz")
  188. assert.NoError(t, err)
  189. zr, err := gzip.NewReader(f)
  190. assert.NoError(t, err)
  191. data, err := ioutil.ReadAll(zr)
  192. assert.NoError(t, err)
  193. original, err := ioutil.ReadFile(nonGzip)
  194. assert.NoError(t, err)
  195. assert.Equal(t, original, data)
  196. }