log.go 6.8 KB

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