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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. "runtime"
  9. "strings"
  10. "sync"
  11. )
  12. type loggerMap struct {
  13. sync.Map
  14. }
  15. func (m *loggerMap) Load(k string) (*Logger, bool) {
  16. v, ok := m.Map.Load(k)
  17. if !ok {
  18. return nil, false
  19. }
  20. l, ok := v.(*Logger)
  21. return l, ok
  22. }
  23. func (m *loggerMap) Store(k string, v *Logger) {
  24. m.Map.Store(k, v)
  25. }
  26. func (m *loggerMap) Delete(k string) {
  27. m.Map.Delete(k)
  28. }
  29. var (
  30. // DEFAULT is the name of the default logger
  31. DEFAULT = "default"
  32. // NamedLoggers map of named loggers
  33. NamedLoggers loggerMap
  34. prefix string
  35. )
  36. // NewLogger create a logger for the default logger
  37. func NewLogger(bufLen int64, name, provider, config string) *Logger {
  38. err := NewNamedLogger(DEFAULT, bufLen, name, provider, config)
  39. if err != nil {
  40. CriticalWithSkip(1, "Unable to create default logger: %v", err)
  41. panic(err)
  42. }
  43. l, _ := NamedLoggers.Load(DEFAULT)
  44. return l
  45. }
  46. // NewNamedLogger creates a new named logger for a given configuration
  47. func NewNamedLogger(name string, bufLen int64, subname, provider, config string) error {
  48. logger, ok := NamedLoggers.Load(name)
  49. if !ok {
  50. logger = newLogger(name, bufLen)
  51. NamedLoggers.Store(name, logger)
  52. }
  53. return logger.SetLogger(subname, provider, config)
  54. }
  55. // DelNamedLogger closes and deletes the named logger
  56. func DelNamedLogger(name string) {
  57. l, ok := NamedLoggers.Load(name)
  58. if ok {
  59. NamedLoggers.Delete(name)
  60. l.Close()
  61. }
  62. }
  63. // DelLogger removes the named sublogger from the default logger
  64. func DelLogger(name string) error {
  65. logger, _ := NamedLoggers.Load(DEFAULT)
  66. found, err := logger.DelLogger(name)
  67. if !found {
  68. Trace("Log %s not found, no need to delete", name)
  69. }
  70. return err
  71. }
  72. // GetLogger returns either a named logger or the default logger
  73. func GetLogger(name string) *Logger {
  74. logger, ok := NamedLoggers.Load(name)
  75. if ok {
  76. return logger
  77. }
  78. logger, _ = NamedLoggers.Load(DEFAULT)
  79. return logger
  80. }
  81. // GetLevel returns the minimum logger level
  82. func GetLevel() Level {
  83. l, _ := NamedLoggers.Load(DEFAULT)
  84. return l.GetLevel()
  85. }
  86. // GetStacktraceLevel returns the minimum logger level
  87. func GetStacktraceLevel() Level {
  88. l, _ := NamedLoggers.Load(DEFAULT)
  89. return l.GetStacktraceLevel()
  90. }
  91. // Trace records trace log
  92. func Trace(format string, v ...interface{}) {
  93. Log(1, TRACE, format, v...)
  94. }
  95. // IsTrace returns true if at least one logger is TRACE
  96. func IsTrace() bool {
  97. return GetLevel() <= TRACE
  98. }
  99. // Debug records debug log
  100. func Debug(format string, v ...interface{}) {
  101. Log(1, DEBUG, format, v...)
  102. }
  103. // IsDebug returns true if at least one logger is DEBUG
  104. func IsDebug() bool {
  105. return GetLevel() <= DEBUG
  106. }
  107. // Info records info log
  108. func Info(format string, v ...interface{}) {
  109. Log(1, INFO, format, v...)
  110. }
  111. // IsInfo returns true if at least one logger is INFO
  112. func IsInfo() bool {
  113. return GetLevel() <= INFO
  114. }
  115. // Warn records warning log
  116. func Warn(format string, v ...interface{}) {
  117. Log(1, WARN, format, v...)
  118. }
  119. // IsWarn returns true if at least one logger is WARN
  120. func IsWarn() bool {
  121. return GetLevel() <= WARN
  122. }
  123. // Error records error log
  124. func Error(format string, v ...interface{}) {
  125. Log(1, ERROR, format, v...)
  126. }
  127. // ErrorWithSkip records error log from "skip" calls back from this function
  128. func ErrorWithSkip(skip int, format string, v ...interface{}) {
  129. Log(skip+1, ERROR, format, v...)
  130. }
  131. // IsError returns true if at least one logger is ERROR
  132. func IsError() bool {
  133. return GetLevel() <= ERROR
  134. }
  135. // Critical records critical log
  136. func Critical(format string, v ...interface{}) {
  137. Log(1, CRITICAL, format, v...)
  138. }
  139. // CriticalWithSkip records critical log from "skip" calls back from this function
  140. func CriticalWithSkip(skip int, format string, v ...interface{}) {
  141. Log(skip+1, CRITICAL, format, v...)
  142. }
  143. // IsCritical returns true if at least one logger is CRITICAL
  144. func IsCritical() bool {
  145. return GetLevel() <= CRITICAL
  146. }
  147. // Fatal records fatal log and exit process
  148. func Fatal(format string, v ...interface{}) {
  149. Log(1, FATAL, format, v...)
  150. Close()
  151. os.Exit(1)
  152. }
  153. // FatalWithSkip records fatal log from "skip" calls back from this function
  154. func FatalWithSkip(skip int, format string, v ...interface{}) {
  155. Log(skip+1, FATAL, format, v...)
  156. Close()
  157. os.Exit(1)
  158. }
  159. // IsFatal returns true if at least one logger is FATAL
  160. func IsFatal() bool {
  161. return GetLevel() <= FATAL
  162. }
  163. // Pause pauses all the loggers
  164. func Pause() {
  165. NamedLoggers.Range(func(key, value interface{}) bool {
  166. logger := value.(*Logger)
  167. logger.Pause()
  168. logger.Flush()
  169. return true
  170. })
  171. }
  172. // Resume resumes all the loggers
  173. func Resume() {
  174. NamedLoggers.Range(func(key, value interface{}) bool {
  175. logger := value.(*Logger)
  176. logger.Resume()
  177. return true
  178. })
  179. }
  180. // ReleaseReopen releases and reopens logging files
  181. func ReleaseReopen() error {
  182. var accumulatedErr error
  183. NamedLoggers.Range(func(key, value interface{}) bool {
  184. logger := value.(*Logger)
  185. if err := logger.ReleaseReopen(); err != nil {
  186. if accumulatedErr == nil {
  187. accumulatedErr = fmt.Errorf("Error reopening %s: %v", key.(string), err)
  188. } else {
  189. accumulatedErr = fmt.Errorf("Error reopening %s: %v & %v", key.(string), err, accumulatedErr)
  190. }
  191. }
  192. return true
  193. })
  194. return accumulatedErr
  195. }
  196. // Close closes all the loggers
  197. func Close() {
  198. l, ok := NamedLoggers.Load(DEFAULT)
  199. if !ok {
  200. return
  201. }
  202. NamedLoggers.Delete(DEFAULT)
  203. l.Close()
  204. }
  205. // Log a message with defined skip and at logging level
  206. // A skip of 0 refers to the caller of this command
  207. func Log(skip int, level Level, format string, v ...interface{}) {
  208. l, ok := NamedLoggers.Load(DEFAULT)
  209. if ok {
  210. l.Log(skip+1, level, format, v...)
  211. }
  212. }
  213. // LoggerAsWriter is a io.Writer shim around the gitea log
  214. type LoggerAsWriter struct {
  215. ourLoggers []*Logger
  216. level Level
  217. }
  218. // NewLoggerAsWriter creates a Writer representation of the logger with setable log level
  219. func NewLoggerAsWriter(level string, ourLoggers ...*Logger) *LoggerAsWriter {
  220. if len(ourLoggers) == 0 {
  221. l, _ := NamedLoggers.Load(DEFAULT)
  222. ourLoggers = []*Logger{l}
  223. }
  224. l := &LoggerAsWriter{
  225. ourLoggers: ourLoggers,
  226. level: FromString(level),
  227. }
  228. return l
  229. }
  230. // Write implements the io.Writer interface to allow spoofing of macaron
  231. func (l *LoggerAsWriter) Write(p []byte) (int, error) {
  232. for _, logger := range l.ourLoggers {
  233. // Skip = 3 because this presumes that we have been called by log.Println()
  234. // If the caller has used log.Output or the like this will be wrong
  235. logger.Log(3, l.level, string(p))
  236. }
  237. return len(p), nil
  238. }
  239. // Log takes a given string and logs it at the set log-level
  240. func (l *LoggerAsWriter) Log(msg string) {
  241. for _, logger := range l.ourLoggers {
  242. // Set the skip to reference the call just above this
  243. _ = logger.Log(1, l.level, msg)
  244. }
  245. }
  246. func init() {
  247. _, filename, _, _ := runtime.Caller(0)
  248. prefix = strings.TrimSuffix(filename, "modules/log/log.go")
  249. }