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.

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