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.

log.go 6.6KB

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