Fork to maintain patches against the official gitea for https://code.ceondo.com https://github.com/go-gitea/gitea

log.go 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. // Copyright 2014 The Gogs 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. "fmt"
  7. "os"
  8. "path"
  9. "path/filepath"
  10. "runtime"
  11. "strings"
  12. "sync"
  13. )
  14. var (
  15. loggers []*Logger
  16. // GitLogger logger for git
  17. GitLogger *Logger
  18. )
  19. // NewLogger create a logger
  20. func NewLogger(bufLen int64, mode, config string) {
  21. logger := newLogger(bufLen)
  22. isExist := false
  23. for i, l := range loggers {
  24. if l.adapter == mode {
  25. isExist = true
  26. loggers[i] = logger
  27. }
  28. }
  29. if !isExist {
  30. loggers = append(loggers, logger)
  31. }
  32. if err := logger.SetLogger(mode, config); err != nil {
  33. Fatal(2, "Failed to set logger (%s): %v", mode, err)
  34. }
  35. }
  36. // DelLogger removes loggers that are for the given mode
  37. func DelLogger(mode string) error {
  38. for _, l := range loggers {
  39. if _, ok := l.outputs[mode]; ok {
  40. return l.DelLogger(mode)
  41. }
  42. }
  43. Trace("Log adapter %s not found, no need to delete", mode)
  44. return nil
  45. }
  46. // NewGitLogger create a logger for git
  47. // FIXME: use same log level as other loggers.
  48. func NewGitLogger(logPath string) {
  49. path := path.Dir(logPath)
  50. if err := os.MkdirAll(path, os.ModePerm); err != nil {
  51. Fatal(4, "Failed to create dir %s: %v", path, err)
  52. }
  53. GitLogger = newLogger(0)
  54. GitLogger.SetLogger("file", fmt.Sprintf(`{"level":0,"filename":"%s","rotate":false}`, logPath))
  55. }
  56. // Trace records trace log
  57. func Trace(format string, v ...interface{}) {
  58. for _, logger := range loggers {
  59. logger.Trace(format, v...)
  60. }
  61. }
  62. // Debug records debug log
  63. func Debug(format string, v ...interface{}) {
  64. for _, logger := range loggers {
  65. logger.Debug(format, v...)
  66. }
  67. }
  68. // Info records info log
  69. func Info(format string, v ...interface{}) {
  70. for _, logger := range loggers {
  71. logger.Info(format, v...)
  72. }
  73. }
  74. // Warn records warning log
  75. func Warn(format string, v ...interface{}) {
  76. for _, logger := range loggers {
  77. logger.Warn(format, v...)
  78. }
  79. }
  80. // Error records error log
  81. func Error(skip int, format string, v ...interface{}) {
  82. for _, logger := range loggers {
  83. logger.Error(skip, format, v...)
  84. }
  85. }
  86. // Critical records critical log
  87. func Critical(skip int, format string, v ...interface{}) {
  88. for _, logger := range loggers {
  89. logger.Critical(skip, format, v...)
  90. }
  91. }
  92. // Fatal records error log and exit process
  93. func Fatal(skip int, format string, v ...interface{}) {
  94. Error(skip, format, v...)
  95. for _, l := range loggers {
  96. l.Close()
  97. }
  98. os.Exit(1)
  99. }
  100. // Close closes all the loggers
  101. func Close() {
  102. for _, l := range loggers {
  103. l.Close()
  104. }
  105. }
  106. // .___ __ _____
  107. // | | _____/ |_ ____________/ ____\____ ____ ____
  108. // | |/ \ __\/ __ \_ __ \ __\\__ \ _/ ___\/ __ \
  109. // | | | \ | \ ___/| | \/| | / __ \\ \__\ ___/
  110. // |___|___| /__| \___ >__| |__| (____ /\___ >___ >
  111. // \/ \/ \/ \/ \/
  112. // LogLevel level type for log
  113. //type LogLevel int
  114. // log levels
  115. const (
  116. TRACE = iota
  117. DEBUG
  118. INFO
  119. WARN
  120. ERROR
  121. CRITICAL
  122. FATAL
  123. )
  124. // LoggerInterface represents behaviors of a logger provider.
  125. type LoggerInterface interface {
  126. Init(config string) error
  127. WriteMsg(msg string, skip, level int) error
  128. Destroy()
  129. Flush()
  130. }
  131. type loggerType func() LoggerInterface
  132. var adapters = make(map[string]loggerType)
  133. // Register registers given logger provider to adapters.
  134. func Register(name string, log loggerType) {
  135. if log == nil {
  136. panic("log: register provider is nil")
  137. }
  138. if _, dup := adapters[name]; dup {
  139. panic("log: register called twice for provider \"" + name + "\"")
  140. }
  141. adapters[name] = log
  142. }
  143. type logMsg struct {
  144. skip, level int
  145. msg string
  146. }
  147. // Logger is default logger in beego application.
  148. // it can contain several providers and log message into all providers.
  149. type Logger struct {
  150. adapter string
  151. lock sync.Mutex
  152. level int
  153. msg chan *logMsg
  154. outputs map[string]LoggerInterface
  155. quit chan bool
  156. }
  157. // newLogger initializes and returns a new logger.
  158. func newLogger(buffer int64) *Logger {
  159. l := &Logger{
  160. msg: make(chan *logMsg, buffer),
  161. outputs: make(map[string]LoggerInterface),
  162. quit: make(chan bool),
  163. }
  164. go l.StartLogger()
  165. return l
  166. }
  167. // SetLogger sets new logger instance with given logger adapter and config.
  168. func (l *Logger) SetLogger(adapter string, config string) error {
  169. l.lock.Lock()
  170. defer l.lock.Unlock()
  171. if log, ok := adapters[adapter]; ok {
  172. lg := log()
  173. if err := lg.Init(config); err != nil {
  174. return err
  175. }
  176. l.outputs[adapter] = lg
  177. l.adapter = adapter
  178. } else {
  179. panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)")
  180. }
  181. return nil
  182. }
  183. // DelLogger removes a logger adapter instance.
  184. func (l *Logger) DelLogger(adapter string) error {
  185. l.lock.Lock()
  186. defer l.lock.Unlock()
  187. if lg, ok := l.outputs[adapter]; ok {
  188. lg.Destroy()
  189. delete(l.outputs, adapter)
  190. } else {
  191. panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)")
  192. }
  193. return nil
  194. }
  195. func (l *Logger) writerMsg(skip, level int, msg string) error {
  196. if l.level > level {
  197. return nil
  198. }
  199. lm := &logMsg{
  200. skip: skip,
  201. level: level,
  202. }
  203. // Only error information needs locate position for debugging.
  204. if lm.level >= ERROR {
  205. pc, file, line, ok := runtime.Caller(skip)
  206. if ok {
  207. // Get caller function name.
  208. fn := runtime.FuncForPC(pc)
  209. var fnName string
  210. if fn == nil {
  211. fnName = "?()"
  212. } else {
  213. fnName = strings.TrimLeft(filepath.Ext(fn.Name()), ".") + "()"
  214. }
  215. fileName := file
  216. if len(fileName) > 20 {
  217. fileName = "..." + fileName[len(fileName)-20:]
  218. }
  219. lm.msg = fmt.Sprintf("[%s:%d %s] %s", fileName, line, fnName, msg)
  220. } else {
  221. lm.msg = msg
  222. }
  223. } else {
  224. lm.msg = msg
  225. }
  226. l.msg <- lm
  227. return nil
  228. }
  229. // StartLogger starts logger chan reading.
  230. func (l *Logger) StartLogger() {
  231. for {
  232. select {
  233. case bm := <-l.msg:
  234. for _, l := range l.outputs {
  235. if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil {
  236. fmt.Println("ERROR, unable to WriteMsg:", err)
  237. }
  238. }
  239. case <-l.quit:
  240. return
  241. }
  242. }
  243. }
  244. // Flush flushes all chan data.
  245. func (l *Logger) Flush() {
  246. for _, l := range l.outputs {
  247. l.Flush()
  248. }
  249. }
  250. // Close closes logger, flush all chan data and destroy all adapter instances.
  251. func (l *Logger) Close() {
  252. l.quit <- true
  253. for {
  254. if len(l.msg) > 0 {
  255. bm := <-l.msg
  256. for _, l := range l.outputs {
  257. if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil {
  258. fmt.Println("ERROR, unable to WriteMsg:", err)
  259. }
  260. }
  261. } else {
  262. break
  263. }
  264. }
  265. for _, l := range l.outputs {
  266. l.Flush()
  267. l.Destroy()
  268. }
  269. }
  270. // Trace records trace log
  271. func (l *Logger) Trace(format string, v ...interface{}) {
  272. msg := fmt.Sprintf("[T] "+format, v...)
  273. l.writerMsg(0, TRACE, msg)
  274. }
  275. // Debug records debug log
  276. func (l *Logger) Debug(format string, v ...interface{}) {
  277. msg := fmt.Sprintf("[D] "+format, v...)
  278. l.writerMsg(0, DEBUG, msg)
  279. }
  280. // Info records information log
  281. func (l *Logger) Info(format string, v ...interface{}) {
  282. msg := fmt.Sprintf("[I] "+format, v...)
  283. l.writerMsg(0, INFO, msg)
  284. }
  285. // Warn records warning log
  286. func (l *Logger) Warn(format string, v ...interface{}) {
  287. msg := fmt.Sprintf("[W] "+format, v...)
  288. l.writerMsg(0, WARN, msg)
  289. }
  290. // Error records error log
  291. func (l *Logger) Error(skip int, format string, v ...interface{}) {
  292. msg := fmt.Sprintf("[E] "+format, v...)
  293. l.writerMsg(skip, ERROR, msg)
  294. }
  295. // Critical records critical log
  296. func (l *Logger) Critical(skip int, format string, v ...interface{}) {
  297. msg := fmt.Sprintf("[C] "+format, v...)
  298. l.writerMsg(skip, CRITICAL, msg)
  299. }
  300. // Fatal records error log and exit the process
  301. func (l *Logger) Fatal(skip int, format string, v ...interface{}) {
  302. msg := fmt.Sprintf("[F] "+format, v...)
  303. l.writerMsg(skip, FATAL, msg)
  304. l.Close()
  305. os.Exit(1)
  306. }