log.go 6.6 KB

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