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.

297 lines
6.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  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(1, "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. // .___ __ _____
  77. // | | _____/ |_ ____________/ ____\____ ____ ____
  78. // | |/ \ __\/ __ \_ __ \ __\\__ \ _/ ___\/ __ \
  79. // | | | \ | \ ___/| | \/| | / __ \\ \__\ ___/
  80. // |___|___| /__| \___ >__| |__| (____ /\___ >___ >
  81. // \/ \/ \/ \/ \/
  82. type LogLevel int
  83. const (
  84. TRACE = iota
  85. DEBUG
  86. INFO
  87. WARN
  88. ERROR
  89. CRITICAL
  90. FATAL
  91. )
  92. // LoggerInterface represents behaviors of a logger provider.
  93. type LoggerInterface interface {
  94. Init(config string) error
  95. WriteMsg(msg string, skip, level int) error
  96. Destroy()
  97. Flush()
  98. }
  99. type loggerType func() LoggerInterface
  100. var adapters = make(map[string]loggerType)
  101. // Register registers given logger provider to adapters.
  102. func Register(name string, log loggerType) {
  103. if log == nil {
  104. panic("log: register provider is nil")
  105. }
  106. if _, dup := adapters[name]; dup {
  107. panic("log: register called twice for provider \"" + name + "\"")
  108. }
  109. adapters[name] = log
  110. }
  111. type logMsg struct {
  112. skip, level int
  113. msg string
  114. }
  115. // Logger is default logger in beego application.
  116. // it can contain several providers and log message into all providers.
  117. type Logger struct {
  118. adapter string
  119. lock sync.Mutex
  120. level int
  121. msg chan *logMsg
  122. outputs map[string]LoggerInterface
  123. quit chan bool
  124. }
  125. // newLogger initializes and returns a new logger.
  126. func newLogger(buffer int64) *Logger {
  127. l := &Logger{
  128. msg: make(chan *logMsg, buffer),
  129. outputs: make(map[string]LoggerInterface),
  130. quit: make(chan bool),
  131. }
  132. go l.StartLogger()
  133. return l
  134. }
  135. // SetLogger sets new logger instanse with given logger adapter and config.
  136. func (l *Logger) SetLogger(adapter string, config string) error {
  137. l.lock.Lock()
  138. defer l.lock.Unlock()
  139. if log, ok := adapters[adapter]; ok {
  140. lg := log()
  141. if err := lg.Init(config); err != nil {
  142. return err
  143. }
  144. l.outputs[adapter] = lg
  145. l.adapter = adapter
  146. } else {
  147. panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)")
  148. }
  149. return nil
  150. }
  151. // DelLogger removes a logger adapter instance.
  152. func (l *Logger) DelLogger(adapter string) error {
  153. l.lock.Lock()
  154. defer l.lock.Unlock()
  155. if lg, ok := l.outputs[adapter]; ok {
  156. lg.Destroy()
  157. delete(l.outputs, adapter)
  158. } else {
  159. panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)")
  160. }
  161. return nil
  162. }
  163. func (l *Logger) writerMsg(skip, level int, msg string) error {
  164. if l.level > level {
  165. return nil
  166. }
  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. l.WriteMsg(bm.msg, bm.skip, bm.level)
  200. }
  201. case <-l.quit:
  202. return
  203. }
  204. }
  205. }
  206. // Flush flushs all chan data.
  207. func (l *Logger) Flush() {
  208. for _, l := range l.outputs {
  209. l.Flush()
  210. }
  211. }
  212. // Close closes logger, flush all chan data and destroy all adapter instances.
  213. func (l *Logger) Close() {
  214. l.quit <- true
  215. for {
  216. if len(l.msg) > 0 {
  217. bm := <-l.msg
  218. for _, l := range l.outputs {
  219. l.WriteMsg(bm.msg, bm.skip, bm.level)
  220. }
  221. } else {
  222. break
  223. }
  224. }
  225. for _, l := range l.outputs {
  226. l.Flush()
  227. l.Destroy()
  228. }
  229. }
  230. func (l *Logger) Trace(format string, v ...interface{}) {
  231. msg := fmt.Sprintf("[T] "+format, v...)
  232. l.writerMsg(0, TRACE, msg)
  233. }
  234. func (l *Logger) Debug(format string, v ...interface{}) {
  235. msg := fmt.Sprintf("[D] "+format, v...)
  236. l.writerMsg(0, DEBUG, msg)
  237. }
  238. func (l *Logger) Info(format string, v ...interface{}) {
  239. msg := fmt.Sprintf("[I] "+format, v...)
  240. l.writerMsg(0, INFO, msg)
  241. }
  242. func (l *Logger) Warn(format string, v ...interface{}) {
  243. msg := fmt.Sprintf("[W] "+format, v...)
  244. l.writerMsg(0, WARN, msg)
  245. }
  246. func (l *Logger) Error(skip int, format string, v ...interface{}) {
  247. msg := fmt.Sprintf("[E] "+format, v...)
  248. l.writerMsg(skip, ERROR, msg)
  249. }
  250. func (l *Logger) Critical(skip int, format string, v ...interface{}) {
  251. msg := fmt.Sprintf("[C] "+format, v...)
  252. l.writerMsg(skip, CRITICAL, msg)
  253. }
  254. func (l *Logger) Fatal(skip int, format string, v ...interface{}) {
  255. msg := fmt.Sprintf("[F] "+format, v...)
  256. l.writerMsg(skip, FATAL, msg)
  257. l.Close()
  258. os.Exit(1)
  259. }