log.go 6.6 KB

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