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.

311 lines
6.6 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. 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. }