123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- // Copyright 2015 The Prometheus Authors
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package log
- import (
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net/url"
- "os"
- "runtime"
- "strconv"
- "strings"
- "github.com/sirupsen/logrus"
- )
- type levelFlag string
- // String implements flag.Value.
- func (f levelFlag) String() string {
- return fmt.Sprintf("%q", origLogger.Level.String())
- }
- // Set implements flag.Value.
- func (f levelFlag) Set(level string) error {
- l, err := logrus.ParseLevel(level)
- if err != nil {
- return err
- }
- origLogger.Level = l
- return nil
- }
- // setSyslogFormatter is nil if the target architecture does not support syslog.
- var setSyslogFormatter func(logger, string, string) error
- // setEventlogFormatter is nil if the target OS does not support Eventlog (i.e., is not Windows).
- var setEventlogFormatter func(logger, string, bool) error
- func setJSONFormatter() {
- origLogger.Formatter = &logrus.JSONFormatter{}
- }
- type logFormatFlag url.URL
- // String implements flag.Value.
- func (f logFormatFlag) String() string {
- u := url.URL(f)
- return fmt.Sprintf("%q", u.String())
- }
- // Set implements flag.Value.
- func (f logFormatFlag) Set(format string) error {
- return baseLogger.SetFormat(format)
- }
- func init() {
- AddFlags(flag.CommandLine)
- }
- // AddFlags adds the flags used by this package to the given FlagSet. That's
- // useful if working with a custom FlagSet. The init function of this package
- // adds the flags to flag.CommandLine anyway. Thus, it's usually enough to call
- // flag.Parse() to make the logging flags take effect.
- func AddFlags(fs *flag.FlagSet) {
- fs.Var(
- levelFlag(origLogger.Level.String()),
- "log.level",
- "Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]",
- )
- fs.Var(
- logFormatFlag(url.URL{Scheme: "logger", Opaque: "stderr"}),
- "log.format",
- `Set the log target and format. Example: "logger:syslog?appname=bob&local=7" or "logger:stdout?json=true"`,
- )
- }
- // Logger is the interface for loggers used in the Prometheus components.
- type Logger interface {
- Debug(...interface{})
- Debugln(...interface{})
- Debugf(string, ...interface{})
- Info(...interface{})
- Infoln(...interface{})
- Infof(string, ...interface{})
- Warn(...interface{})
- Warnln(...interface{})
- Warnf(string, ...interface{})
- Error(...interface{})
- Errorln(...interface{})
- Errorf(string, ...interface{})
- Fatal(...interface{})
- Fatalln(...interface{})
- Fatalf(string, ...interface{})
- With(key string, value interface{}) Logger
- SetFormat(string) error
- SetLevel(string) error
- }
- type logger struct {
- entry *logrus.Entry
- }
- func (l logger) With(key string, value interface{}) Logger {
- return logger{l.entry.WithField(key, value)}
- }
- // Debug logs a message at level Debug on the standard logger.
- func (l logger) Debug(args ...interface{}) {
- l.sourced().Debug(args...)
- }
- // Debug logs a message at level Debug on the standard logger.
- func (l logger) Debugln(args ...interface{}) {
- l.sourced().Debugln(args...)
- }
- // Debugf logs a message at level Debug on the standard logger.
- func (l logger) Debugf(format string, args ...interface{}) {
- l.sourced().Debugf(format, args...)
- }
- // Info logs a message at level Info on the standard logger.
- func (l logger) Info(args ...interface{}) {
- l.sourced().Info(args...)
- }
- // Info logs a message at level Info on the standard logger.
- func (l logger) Infoln(args ...interface{}) {
- l.sourced().Infoln(args...)
- }
- // Infof logs a message at level Info on the standard logger.
- func (l logger) Infof(format string, args ...interface{}) {
- l.sourced().Infof(format, args...)
- }
- // Warn logs a message at level Warn on the standard logger.
- func (l logger) Warn(args ...interface{}) {
- l.sourced().Warn(args...)
- }
- // Warn logs a message at level Warn on the standard logger.
- func (l logger) Warnln(args ...interface{}) {
- l.sourced().Warnln(args...)
- }
- // Warnf logs a message at level Warn on the standard logger.
- func (l logger) Warnf(format string, args ...interface{}) {
- l.sourced().Warnf(format, args...)
- }
- // Error logs a message at level Error on the standard logger.
- func (l logger) Error(args ...interface{}) {
- l.sourced().Error(args...)
- }
- // Error logs a message at level Error on the standard logger.
- func (l logger) Errorln(args ...interface{}) {
- l.sourced().Errorln(args...)
- }
- // Errorf logs a message at level Error on the standard logger.
- func (l logger) Errorf(format string, args ...interface{}) {
- l.sourced().Errorf(format, args...)
- }
- // Fatal logs a message at level Fatal on the standard logger.
- func (l logger) Fatal(args ...interface{}) {
- l.sourced().Fatal(args...)
- }
- // Fatal logs a message at level Fatal on the standard logger.
- func (l logger) Fatalln(args ...interface{}) {
- l.sourced().Fatalln(args...)
- }
- // Fatalf logs a message at level Fatal on the standard logger.
- func (l logger) Fatalf(format string, args ...interface{}) {
- l.sourced().Fatalf(format, args...)
- }
- func (l logger) SetLevel(level string) error {
- lvl, err := logrus.ParseLevel(level)
- if err != nil {
- return err
- }
- l.entry.Logger.Level = lvl
- return nil
- }
- func (l logger) SetFormat(format string) error {
- u, err := url.Parse(format)
- if err != nil {
- return err
- }
- if u.Scheme != "logger" {
- return fmt.Errorf("invalid scheme %s", u.Scheme)
- }
- jsonq := u.Query().Get("json")
- if jsonq == "true" {
- setJSONFormatter()
- }
- switch u.Opaque {
- case "syslog":
- if setSyslogFormatter == nil {
- return fmt.Errorf("system does not support syslog")
- }
- appname := u.Query().Get("appname")
- facility := u.Query().Get("local")
- return setSyslogFormatter(l, appname, facility)
- case "eventlog":
- if setEventlogFormatter == nil {
- return fmt.Errorf("system does not support eventlog")
- }
- name := u.Query().Get("name")
- debugAsInfo := false
- debugAsInfoRaw := u.Query().Get("debugAsInfo")
- if parsedDebugAsInfo, err := strconv.ParseBool(debugAsInfoRaw); err == nil {
- debugAsInfo = parsedDebugAsInfo
- }
- return setEventlogFormatter(l, name, debugAsInfo)
- case "stdout":
- l.entry.Logger.Out = os.Stdout
- case "stderr":
- l.entry.Logger.Out = os.Stderr
- default:
- return fmt.Errorf("unsupported logger %q", u.Opaque)
- }
- return nil
- }
- // sourced adds a source field to the logger that contains
- // the file name and line where the logging happened.
- func (l logger) sourced() *logrus.Entry {
- _, file, line, ok := runtime.Caller(2)
- if !ok {
- file = "<???>"
- line = 1
- } else {
- slash := strings.LastIndex(file, "/")
- file = file[slash+1:]
- }
- return l.entry.WithField("source", fmt.Sprintf("%s:%d", file, line))
- }
- var origLogger = logrus.New()
- var baseLogger = logger{entry: logrus.NewEntry(origLogger)}
- // Base returns the default Logger logging to
- func Base() Logger {
- return baseLogger
- }
- // NewLogger returns a new Logger logging to out.
- func NewLogger(w io.Writer) Logger {
- l := logrus.New()
- l.Out = w
- return logger{entry: logrus.NewEntry(l)}
- }
- // NewNopLogger returns a logger that discards all log messages.
- func NewNopLogger() Logger {
- l := logrus.New()
- l.Out = ioutil.Discard
- return logger{entry: logrus.NewEntry(l)}
- }
- // With adds a field to the logger.
- func With(key string, value interface{}) Logger {
- return baseLogger.With(key, value)
- }
- // Debug logs a message at level Debug on the standard logger.
- func Debug(args ...interface{}) {
- baseLogger.sourced().Debug(args...)
- }
- // Debugln logs a message at level Debug on the standard logger.
- func Debugln(args ...interface{}) {
- baseLogger.sourced().Debugln(args...)
- }
- // Debugf logs a message at level Debug on the standard logger.
- func Debugf(format string, args ...interface{}) {
- baseLogger.sourced().Debugf(format, args...)
- }
- // Info logs a message at level Info on the standard logger.
- func Info(args ...interface{}) {
- baseLogger.sourced().Info(args...)
- }
- // Infoln logs a message at level Info on the standard logger.
- func Infoln(args ...interface{}) {
- baseLogger.sourced().Infoln(args...)
- }
- // Infof logs a message at level Info on the standard logger.
- func Infof(format string, args ...interface{}) {
- baseLogger.sourced().Infof(format, args...)
- }
- // Warn logs a message at level Warn on the standard logger.
- func Warn(args ...interface{}) {
- baseLogger.sourced().Warn(args...)
- }
- // Warnln logs a message at level Warn on the standard logger.
- func Warnln(args ...interface{}) {
- baseLogger.sourced().Warnln(args...)
- }
- // Warnf logs a message at level Warn on the standard logger.
- func Warnf(format string, args ...interface{}) {
- baseLogger.sourced().Warnf(format, args...)
- }
- // Error logs a message at level Error on the standard logger.
- func Error(args ...interface{}) {
- baseLogger.sourced().Error(args...)
- }
- // Errorln logs a message at level Error on the standard logger.
- func Errorln(args ...interface{}) {
- baseLogger.sourced().Errorln(args...)
- }
- // Errorf logs a message at level Error on the standard logger.
- func Errorf(format string, args ...interface{}) {
- baseLogger.sourced().Errorf(format, args...)
- }
- // Fatal logs a message at level Fatal on the standard logger.
- func Fatal(args ...interface{}) {
- baseLogger.sourced().Fatal(args...)
- }
- // Fatalln logs a message at level Fatal on the standard logger.
- func Fatalln(args ...interface{}) {
- baseLogger.sourced().Fatalln(args...)
- }
- // Fatalf logs a message at level Fatal on the standard logger.
- func Fatalf(format string, args ...interface{}) {
- baseLogger.sourced().Fatalf(format, args...)
- }
- type errorLogWriter struct{}
- func (errorLogWriter) Write(b []byte) (int, error) {
- baseLogger.sourced().Error(string(b))
- return len(b), nil
- }
- // NewErrorLogger returns a log.Logger that is meant to be used
- // in the ErrorLog field of an http.Server to log HTTP server errors.
- func NewErrorLogger() *log.Logger {
- return log.New(&errorLogWriter{}, "", 0)
- }
|