log.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. // Copyright 2015 The Prometheus Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package log
  14. import (
  15. "flag"
  16. "fmt"
  17. "io"
  18. "io/ioutil"
  19. "log"
  20. "net/url"
  21. "os"
  22. "runtime"
  23. "strconv"
  24. "strings"
  25. "github.com/sirupsen/logrus"
  26. )
  27. type levelFlag string
  28. // String implements flag.Value.
  29. func (f levelFlag) String() string {
  30. return fmt.Sprintf("%q", origLogger.Level.String())
  31. }
  32. // Set implements flag.Value.
  33. func (f levelFlag) Set(level string) error {
  34. l, err := logrus.ParseLevel(level)
  35. if err != nil {
  36. return err
  37. }
  38. origLogger.Level = l
  39. return nil
  40. }
  41. // setSyslogFormatter is nil if the target architecture does not support syslog.
  42. var setSyslogFormatter func(logger, string, string) error
  43. // setEventlogFormatter is nil if the target OS does not support Eventlog (i.e., is not Windows).
  44. var setEventlogFormatter func(logger, string, bool) error
  45. func setJSONFormatter() {
  46. origLogger.Formatter = &logrus.JSONFormatter{}
  47. }
  48. type logFormatFlag url.URL
  49. // String implements flag.Value.
  50. func (f logFormatFlag) String() string {
  51. u := url.URL(f)
  52. return fmt.Sprintf("%q", u.String())
  53. }
  54. // Set implements flag.Value.
  55. func (f logFormatFlag) Set(format string) error {
  56. return baseLogger.SetFormat(format)
  57. }
  58. func init() {
  59. AddFlags(flag.CommandLine)
  60. }
  61. // AddFlags adds the flags used by this package to the given FlagSet. That's
  62. // useful if working with a custom FlagSet. The init function of this package
  63. // adds the flags to flag.CommandLine anyway. Thus, it's usually enough to call
  64. // flag.Parse() to make the logging flags take effect.
  65. func AddFlags(fs *flag.FlagSet) {
  66. fs.Var(
  67. levelFlag(origLogger.Level.String()),
  68. "log.level",
  69. "Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]",
  70. )
  71. fs.Var(
  72. logFormatFlag(url.URL{Scheme: "logger", Opaque: "stderr"}),
  73. "log.format",
  74. `Set the log target and format. Example: "logger:syslog?appname=bob&local=7" or "logger:stdout?json=true"`,
  75. )
  76. }
  77. // Logger is the interface for loggers used in the Prometheus components.
  78. type Logger interface {
  79. Debug(...interface{})
  80. Debugln(...interface{})
  81. Debugf(string, ...interface{})
  82. Info(...interface{})
  83. Infoln(...interface{})
  84. Infof(string, ...interface{})
  85. Warn(...interface{})
  86. Warnln(...interface{})
  87. Warnf(string, ...interface{})
  88. Error(...interface{})
  89. Errorln(...interface{})
  90. Errorf(string, ...interface{})
  91. Fatal(...interface{})
  92. Fatalln(...interface{})
  93. Fatalf(string, ...interface{})
  94. With(key string, value interface{}) Logger
  95. SetFormat(string) error
  96. SetLevel(string) error
  97. }
  98. type logger struct {
  99. entry *logrus.Entry
  100. }
  101. func (l logger) With(key string, value interface{}) Logger {
  102. return logger{l.entry.WithField(key, value)}
  103. }
  104. // Debug logs a message at level Debug on the standard logger.
  105. func (l logger) Debug(args ...interface{}) {
  106. l.sourced().Debug(args...)
  107. }
  108. // Debug logs a message at level Debug on the standard logger.
  109. func (l logger) Debugln(args ...interface{}) {
  110. l.sourced().Debugln(args...)
  111. }
  112. // Debugf logs a message at level Debug on the standard logger.
  113. func (l logger) Debugf(format string, args ...interface{}) {
  114. l.sourced().Debugf(format, args...)
  115. }
  116. // Info logs a message at level Info on the standard logger.
  117. func (l logger) Info(args ...interface{}) {
  118. l.sourced().Info(args...)
  119. }
  120. // Info logs a message at level Info on the standard logger.
  121. func (l logger) Infoln(args ...interface{}) {
  122. l.sourced().Infoln(args...)
  123. }
  124. // Infof logs a message at level Info on the standard logger.
  125. func (l logger) Infof(format string, args ...interface{}) {
  126. l.sourced().Infof(format, args...)
  127. }
  128. // Warn logs a message at level Warn on the standard logger.
  129. func (l logger) Warn(args ...interface{}) {
  130. l.sourced().Warn(args...)
  131. }
  132. // Warn logs a message at level Warn on the standard logger.
  133. func (l logger) Warnln(args ...interface{}) {
  134. l.sourced().Warnln(args...)
  135. }
  136. // Warnf logs a message at level Warn on the standard logger.
  137. func (l logger) Warnf(format string, args ...interface{}) {
  138. l.sourced().Warnf(format, args...)
  139. }
  140. // Error logs a message at level Error on the standard logger.
  141. func (l logger) Error(args ...interface{}) {
  142. l.sourced().Error(args...)
  143. }
  144. // Error logs a message at level Error on the standard logger.
  145. func (l logger) Errorln(args ...interface{}) {
  146. l.sourced().Errorln(args...)
  147. }
  148. // Errorf logs a message at level Error on the standard logger.
  149. func (l logger) Errorf(format string, args ...interface{}) {
  150. l.sourced().Errorf(format, args...)
  151. }
  152. // Fatal logs a message at level Fatal on the standard logger.
  153. func (l logger) Fatal(args ...interface{}) {
  154. l.sourced().Fatal(args...)
  155. }
  156. // Fatal logs a message at level Fatal on the standard logger.
  157. func (l logger) Fatalln(args ...interface{}) {
  158. l.sourced().Fatalln(args...)
  159. }
  160. // Fatalf logs a message at level Fatal on the standard logger.
  161. func (l logger) Fatalf(format string, args ...interface{}) {
  162. l.sourced().Fatalf(format, args...)
  163. }
  164. func (l logger) SetLevel(level string) error {
  165. lvl, err := logrus.ParseLevel(level)
  166. if err != nil {
  167. return err
  168. }
  169. l.entry.Logger.Level = lvl
  170. return nil
  171. }
  172. func (l logger) SetFormat(format string) error {
  173. u, err := url.Parse(format)
  174. if err != nil {
  175. return err
  176. }
  177. if u.Scheme != "logger" {
  178. return fmt.Errorf("invalid scheme %s", u.Scheme)
  179. }
  180. jsonq := u.Query().Get("json")
  181. if jsonq == "true" {
  182. setJSONFormatter()
  183. }
  184. switch u.Opaque {
  185. case "syslog":
  186. if setSyslogFormatter == nil {
  187. return fmt.Errorf("system does not support syslog")
  188. }
  189. appname := u.Query().Get("appname")
  190. facility := u.Query().Get("local")
  191. return setSyslogFormatter(l, appname, facility)
  192. case "eventlog":
  193. if setEventlogFormatter == nil {
  194. return fmt.Errorf("system does not support eventlog")
  195. }
  196. name := u.Query().Get("name")
  197. debugAsInfo := false
  198. debugAsInfoRaw := u.Query().Get("debugAsInfo")
  199. if parsedDebugAsInfo, err := strconv.ParseBool(debugAsInfoRaw); err == nil {
  200. debugAsInfo = parsedDebugAsInfo
  201. }
  202. return setEventlogFormatter(l, name, debugAsInfo)
  203. case "stdout":
  204. l.entry.Logger.Out = os.Stdout
  205. case "stderr":
  206. l.entry.Logger.Out = os.Stderr
  207. default:
  208. return fmt.Errorf("unsupported logger %q", u.Opaque)
  209. }
  210. return nil
  211. }
  212. // sourced adds a source field to the logger that contains
  213. // the file name and line where the logging happened.
  214. func (l logger) sourced() *logrus.Entry {
  215. _, file, line, ok := runtime.Caller(2)
  216. if !ok {
  217. file = "<???>"
  218. line = 1
  219. } else {
  220. slash := strings.LastIndex(file, "/")
  221. file = file[slash+1:]
  222. }
  223. return l.entry.WithField("source", fmt.Sprintf("%s:%d", file, line))
  224. }
  225. var origLogger = logrus.New()
  226. var baseLogger = logger{entry: logrus.NewEntry(origLogger)}
  227. // Base returns the default Logger logging to
  228. func Base() Logger {
  229. return baseLogger
  230. }
  231. // NewLogger returns a new Logger logging to out.
  232. func NewLogger(w io.Writer) Logger {
  233. l := logrus.New()
  234. l.Out = w
  235. return logger{entry: logrus.NewEntry(l)}
  236. }
  237. // NewNopLogger returns a logger that discards all log messages.
  238. func NewNopLogger() Logger {
  239. l := logrus.New()
  240. l.Out = ioutil.Discard
  241. return logger{entry: logrus.NewEntry(l)}
  242. }
  243. // With adds a field to the logger.
  244. func With(key string, value interface{}) Logger {
  245. return baseLogger.With(key, value)
  246. }
  247. // Debug logs a message at level Debug on the standard logger.
  248. func Debug(args ...interface{}) {
  249. baseLogger.sourced().Debug(args...)
  250. }
  251. // Debugln logs a message at level Debug on the standard logger.
  252. func Debugln(args ...interface{}) {
  253. baseLogger.sourced().Debugln(args...)
  254. }
  255. // Debugf logs a message at level Debug on the standard logger.
  256. func Debugf(format string, args ...interface{}) {
  257. baseLogger.sourced().Debugf(format, args...)
  258. }
  259. // Info logs a message at level Info on the standard logger.
  260. func Info(args ...interface{}) {
  261. baseLogger.sourced().Info(args...)
  262. }
  263. // Infoln logs a message at level Info on the standard logger.
  264. func Infoln(args ...interface{}) {
  265. baseLogger.sourced().Infoln(args...)
  266. }
  267. // Infof logs a message at level Info on the standard logger.
  268. func Infof(format string, args ...interface{}) {
  269. baseLogger.sourced().Infof(format, args...)
  270. }
  271. // Warn logs a message at level Warn on the standard logger.
  272. func Warn(args ...interface{}) {
  273. baseLogger.sourced().Warn(args...)
  274. }
  275. // Warnln logs a message at level Warn on the standard logger.
  276. func Warnln(args ...interface{}) {
  277. baseLogger.sourced().Warnln(args...)
  278. }
  279. // Warnf logs a message at level Warn on the standard logger.
  280. func Warnf(format string, args ...interface{}) {
  281. baseLogger.sourced().Warnf(format, args...)
  282. }
  283. // Error logs a message at level Error on the standard logger.
  284. func Error(args ...interface{}) {
  285. baseLogger.sourced().Error(args...)
  286. }
  287. // Errorln logs a message at level Error on the standard logger.
  288. func Errorln(args ...interface{}) {
  289. baseLogger.sourced().Errorln(args...)
  290. }
  291. // Errorf logs a message at level Error on the standard logger.
  292. func Errorf(format string, args ...interface{}) {
  293. baseLogger.sourced().Errorf(format, args...)
  294. }
  295. // Fatal logs a message at level Fatal on the standard logger.
  296. func Fatal(args ...interface{}) {
  297. baseLogger.sourced().Fatal(args...)
  298. }
  299. // Fatalln logs a message at level Fatal on the standard logger.
  300. func Fatalln(args ...interface{}) {
  301. baseLogger.sourced().Fatalln(args...)
  302. }
  303. // Fatalf logs a message at level Fatal on the standard logger.
  304. func Fatalf(format string, args ...interface{}) {
  305. baseLogger.sourced().Fatalf(format, args...)
  306. }
  307. type errorLogWriter struct{}
  308. func (errorLogWriter) Write(b []byte) (int, error) {
  309. baseLogger.sourced().Error(string(b))
  310. return len(b), nil
  311. }
  312. // NewErrorLogger returns a log.Logger that is meant to be used
  313. // in the ErrorLog field of an http.Server to log HTTP server errors.
  314. func NewErrorLogger() *log.Logger {
  315. return log.New(&errorLogWriter{}, "", 0)
  316. }