Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. }