diff --git a/cmd/prometheus/main.go b/cmd/prometheus/main.go index a828a84e6..b9f0c1ee4 100644 --- a/cmd/prometheus/main.go +++ b/cmd/prometheus/main.go @@ -27,8 +27,6 @@ import ( "syscall" "time" - k8s_runtime "k8s.io/apimachinery/pkg/util/runtime" - "github.com/asaskevich/govalidator" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" @@ -38,10 +36,12 @@ import ( "github.com/prometheus/common/version" "golang.org/x/net/context" "gopkg.in/alecthomas/kingpin.v2" + k8s_runtime "k8s.io/apimachinery/pkg/util/runtime" + "github.com/prometheus/common/promlog" + promlogflag "github.com/prometheus/common/promlog/flag" "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/notifier" - "github.com/prometheus/prometheus/pkg/promlog" "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/retrieval" "github.com/prometheus/prometheus/rules" @@ -103,9 +103,6 @@ func main() { a.HelpFlag.Short('h') - a.Flag(promlog.LevelFlagName, promlog.LevelFlagHelp). - Default("info").SetValue(&cfg.logLevel) - a.Flag("config.file", "Prometheus configuration file path."). Default("prometheus.yml").StringVar(&cfg.configFile) @@ -173,6 +170,8 @@ func main() { a.Flag("query.max-concurrency", "Maximum number of queries executed concurrently."). Default("20").IntVar(&cfg.queryEngine.MaxConcurrentQueries) + promlogflag.AddFlags(a, &cfg.logLevel) + _, err := a.Parse(os.Args[1:]) if err != nil { a.Usage(os.Args[1:]) @@ -203,7 +202,7 @@ func main() { logger := promlog.New(cfg.logLevel) - // XXX(fabxc): The Kubernetes does background logging which we can only customize by modifying + // XXX(fabxc): Kubernetes does background logging which we can only customize by modifying // a global variable. // Ultimately, here is the best place to set it. k8s_runtime.ErrorHandlers = []func(error){ @@ -284,7 +283,7 @@ func main() { cfg.web.Flags[f.Name] = f.Value.String() } - webHandler := web.New(log.With(logger, "componennt", "web"), &cfg.web) + webHandler := web.New(log.With(logger, "component", "web"), &cfg.web) reloadables = append(reloadables, targetManager, ruleManager, webHandler, notifier) diff --git a/discovery/kubernetes/kubernetes.go b/discovery/kubernetes/kubernetes.go index 17768b879..1226a8edc 100644 --- a/discovery/kubernetes/kubernetes.go +++ b/discovery/kubernetes/kubernetes.go @@ -167,7 +167,7 @@ func (d *Discovery) Run(ctx context.Context, ch chan<- []*config.TargetGroup) { slw := cache.NewListWatchFromClient(rclient, "services", namespace, nil) plw := cache.NewListWatchFromClient(rclient, "pods", namespace, nil) eps := NewEndpoints( - log.With(d.logger, "k8s_sd", "endpoint"), + log.With(d.logger, "role", "endpoint"), cache.NewSharedInformer(slw, &apiv1.Service{}, resyncPeriod), cache.NewSharedInformer(elw, &apiv1.Endpoints{}, resyncPeriod), cache.NewSharedInformer(plw, &apiv1.Pod{}, resyncPeriod), diff --git a/discovery/openstack/hypervisor_test.go b/discovery/openstack/hypervisor_test.go index 4146e4227..1cbf5cfde 100644 --- a/discovery/openstack/hypervisor_test.go +++ b/discovery/openstack/hypervisor_test.go @@ -20,7 +20,6 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "github.com/prometheus/common/log" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" ) @@ -57,7 +56,7 @@ func (s *OpenstackSDHypervisorTestSuite) openstackAuthSuccess() (Discovery, erro Region: "RegionOne", Role: "hypervisor", } - return NewDiscovery(&conf, log.Base()) + return NewDiscovery(&conf, nil) } func (s *OpenstackSDHypervisorTestSuite) TestOpenstackSDHypervisorRefresh() { diff --git a/discovery/openstack/instance.go b/discovery/openstack/instance.go index f426e61c9..5cd8bfb3d 100644 --- a/discovery/openstack/instance.go +++ b/discovery/openstack/instance.go @@ -55,6 +55,9 @@ type InstanceDiscovery struct { // NewInstanceDiscovery returns a new instance discovery. func NewInstanceDiscovery(opts *gophercloud.AuthOptions, interval time.Duration, port int, region string, l log.Logger) *InstanceDiscovery { + if l == nil { + l = log.NewNopLogger() + } return &InstanceDiscovery{authOpts: opts, region: region, interval: interval, port: port, logger: l} } diff --git a/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client_test.go b/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client_test.go index b3567fb75..3903ca9c5 100644 --- a/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client_test.go +++ b/documentation/examples/remote_storage/remote_storage_adapter/influxdb/client_test.go @@ -103,7 +103,7 @@ testmetric,test_label=test_label_value2 value=5.1234 123456789123 Password: "testpass", Timeout: time.Minute, } - c := NewClient(conf, "test_db", "default") + c := NewClient(nil, conf, "test_db", "default") if err := c.Write(samples); err != nil { t.Fatalf("Error sending samples: %s", err) diff --git a/documentation/examples/remote_storage/remote_storage_adapter/main.go b/documentation/examples/remote_storage/remote_storage_adapter/main.go index 5ebd82b84..099820b9e 100644 --- a/documentation/examples/remote_storage/remote_storage_adapter/main.go +++ b/documentation/examples/remote_storage/remote_storage_adapter/main.go @@ -34,10 +34,10 @@ import ( influx "github.com/influxdata/influxdb/client/v2" + "github.com/prometheus/common/promlog" "github.com/prometheus/prometheus/documentation/examples/remote_storage/remote_storage_adapter/graphite" "github.com/prometheus/prometheus/documentation/examples/remote_storage/remote_storage_adapter/influxdb" "github.com/prometheus/prometheus/documentation/examples/remote_storage/remote_storage_adapter/opentsdb" - "github.com/prometheus/prometheus/pkg/promlog" "github.com/prometheus/prometheus/prompb" ) @@ -197,7 +197,7 @@ func buildClients(logger log.Logger, cfg *config) ([]writer, []reader) { writers = append(writers, c) readers = append(readers, c) } - log.Info("Starting up...") + level.Info(logger).Log("Starting up...") return writers, readers } @@ -205,21 +205,21 @@ func serve(logger log.Logger, addr string, writers []writer, readers []reader) e http.HandleFunc("/write", func(w http.ResponseWriter, r *http.Request) { compressed, err := ioutil.ReadAll(r.Body) if err != nil { - log.Errorln("Read error:", err) + level.Error(logger).Log("msg", "Read error", "err", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } reqBuf, err := snappy.Decode(nil, compressed) if err != nil { - log.Errorln("Decode error:", err) + level.Error(logger).Log("msg", "Decode error", "err", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } var req prompb.WriteRequest if err := proto.Unmarshal(reqBuf, &req); err != nil { - log.Errorln("Unmarshal error:", err) + level.Error(logger).Log("msg", "Unmarshal error", "err", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } @@ -241,21 +241,21 @@ func serve(logger log.Logger, addr string, writers []writer, readers []reader) e http.HandleFunc("/read", func(w http.ResponseWriter, r *http.Request) { compressed, err := ioutil.ReadAll(r.Body) if err != nil { - log.Errorln("Read error:", err) + level.Error(logger).Log("msg", "Read error", "err", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } reqBuf, err := snappy.Decode(nil, compressed) if err != nil { - log.Errorln("Decode error:", err) + level.Error(logger).Log("msg", "Decode error", "err", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } var req prompb.ReadRequest if err := proto.Unmarshal(reqBuf, &req); err != nil { - log.Errorln("Unmarshal error:", err) + level.Error(logger).Log("msg", "Unmarshal error", "err", err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } diff --git a/vendor/github.com/go-kit/kit/log/level/doc.go b/vendor/github.com/go-kit/kit/log/level/doc.go new file mode 100644 index 000000000..5e9df7fa1 --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/level/doc.go @@ -0,0 +1,22 @@ +// Package level implements leveled logging on top of package log. To use the +// level package, create a logger as per normal in your func main, and wrap it +// with level.NewFilter. +// +// var logger log.Logger +// logger = log.NewLogfmtLogger(os.Stderr) +// logger = level.NewFilter(logger, level.AllowInfoAndAbove()) // <-- +// logger = log.With(logger, "ts", log.DefaultTimestampUTC) +// +// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error +// helper methods to emit leveled log events. +// +// logger.Log("foo", "bar") // as normal, no level +// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get()) +// if value > 100 { +// level.Error(logger).Log("value", value) +// } +// +// NewFilter allows precise control over what happens when a log event is +// emitted without a level key, or if a squelched level is used. Check the +// Option functions for details. +package level diff --git a/vendor/github.com/go-kit/kit/log/level/level.go b/vendor/github.com/go-kit/kit/log/level/level.go new file mode 100644 index 000000000..6833b0dca --- /dev/null +++ b/vendor/github.com/go-kit/kit/log/level/level.go @@ -0,0 +1,205 @@ +package level + +import "github.com/go-kit/kit/log" + +// Error returns a logger that includes a Key/ErrorValue pair. +func Error(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), ErrorValue()) +} + +// Warn returns a logger that includes a Key/WarnValue pair. +func Warn(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), WarnValue()) +} + +// Info returns a logger that includes a Key/InfoValue pair. +func Info(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), InfoValue()) +} + +// Debug returns a logger that includes a Key/DebugValue pair. +func Debug(logger log.Logger) log.Logger { + return log.WithPrefix(logger, Key(), DebugValue()) +} + +// NewFilter wraps next and implements level filtering. See the commentary on +// the Option functions for a detailed description of how to configure levels. +// If no options are provided, all leveled log events created with Debug, +// Info, Warn or Error helper methods are squelched and non-leveled log +// events are passed to next unmodified. +func NewFilter(next log.Logger, options ...Option) log.Logger { + l := &logger{ + next: next, + } + for _, option := range options { + option(l) + } + return l +} + +type logger struct { + next log.Logger + allowed level + squelchNoLevel bool + errNotAllowed error + errNoLevel error +} + +func (l *logger) Log(keyvals ...interface{}) error { + var hasLevel, levelAllowed bool + for i := 1; i < len(keyvals); i += 2 { + if v, ok := keyvals[i].(*levelValue); ok { + hasLevel = true + levelAllowed = l.allowed&v.level != 0 + break + } + } + if !hasLevel && l.squelchNoLevel { + return l.errNoLevel + } + if hasLevel && !levelAllowed { + return l.errNotAllowed + } + return l.next.Log(keyvals...) +} + +// Option sets a parameter for the leveled logger. +type Option func(*logger) + +// AllowAll is an alias for AllowDebug. +func AllowAll() Option { + return AllowDebug() +} + +// AllowDebug allows error, warn, info and debug level log events to pass. +func AllowDebug() Option { + return allowed(levelError | levelWarn | levelInfo | levelDebug) +} + +// AllowInfo allows error, warn and info level log events to pass. +func AllowInfo() Option { + return allowed(levelError | levelWarn | levelInfo) +} + +// AllowWarn allows error and warn level log events to pass. +func AllowWarn() Option { + return allowed(levelError | levelWarn) +} + +// AllowError allows only error level log events to pass. +func AllowError() Option { + return allowed(levelError) +} + +// AllowNone allows no leveled log events to pass. +func AllowNone() Option { + return allowed(0) +} + +func allowed(allowed level) Option { + return func(l *logger) { l.allowed = allowed } +} + +// ErrNotAllowed sets the error to return from Log when it squelches a log +// event disallowed by the configured Allow[Level] option. By default, +// ErrNotAllowed is nil; in this case the log event is squelched with no +// error. +func ErrNotAllowed(err error) Option { + return func(l *logger) { l.errNotAllowed = err } +} + +// SquelchNoLevel instructs Log to squelch log events with no level, so that +// they don't proceed through to the wrapped logger. If SquelchNoLevel is set +// to true and a log event is squelched in this way, the error value +// configured with ErrNoLevel is returned to the caller. +func SquelchNoLevel(squelch bool) Option { + return func(l *logger) { l.squelchNoLevel = squelch } +} + +// ErrNoLevel sets the error to return from Log when it squelches a log event +// with no level. By default, ErrNoLevel is nil; in this case the log event is +// squelched with no error. +func ErrNoLevel(err error) Option { + return func(l *logger) { l.errNoLevel = err } +} + +// NewInjector wraps next and returns a logger that adds a Key/level pair to +// the beginning of log events that don't already contain a level. In effect, +// this gives a default level to logs without a level. +func NewInjector(next log.Logger, level Value) log.Logger { + return &injector{ + next: next, + level: level, + } +} + +type injector struct { + next log.Logger + level interface{} +} + +func (l *injector) Log(keyvals ...interface{}) error { + for i := 1; i < len(keyvals); i += 2 { + if _, ok := keyvals[i].(*levelValue); ok { + return l.next.Log(keyvals...) + } + } + kvs := make([]interface{}, len(keyvals)+2) + kvs[0], kvs[1] = key, l.level + copy(kvs[2:], keyvals) + return l.next.Log(kvs...) +} + +// Value is the interface that each of the canonical level values implement. +// It contains unexported methods that prevent types from other packages from +// implementing it and guaranteeing that NewFilter can distinguish the levels +// defined in this package from all other values. +type Value interface { + String() string + levelVal() +} + +// Key returns the unique key added to log events by the loggers in this +// package. +func Key() interface{} { return key } + +// ErrorValue returns the unique value added to log events by Error. +func ErrorValue() Value { return errorValue } + +// WarnValue returns the unique value added to log events by Warn. +func WarnValue() Value { return warnValue } + +// InfoValue returns the unique value added to log events by Info. +func InfoValue() Value { return infoValue } + +// DebugValue returns the unique value added to log events by Warn. +func DebugValue() Value { return debugValue } + +var ( + // key is of type interfae{} so that it allocates once during package + // initialization and avoids allocating every type the value is added to a + // []interface{} later. + key interface{} = "level" + + errorValue = &levelValue{level: levelError, name: "error"} + warnValue = &levelValue{level: levelWarn, name: "warn"} + infoValue = &levelValue{level: levelInfo, name: "info"} + debugValue = &levelValue{level: levelDebug, name: "debug"} +) + +type level byte + +const ( + levelDebug level = 1 << iota + levelInfo + levelWarn + levelError +) + +type levelValue struct { + name string + level +} + +func (v *levelValue) String() string { return v.name } +func (v *levelValue) levelVal() {} diff --git a/vendor/github.com/prometheus/common/promlog/flag/flag.go b/vendor/github.com/prometheus/common/promlog/flag/flag.go new file mode 100644 index 000000000..282dfd6eb --- /dev/null +++ b/vendor/github.com/prometheus/common/promlog/flag/flag.go @@ -0,0 +1,33 @@ +// Copyright 2017 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 flag + +import ( + "github.com/prometheus/common/promlog" + kingpin "gopkg.in/alecthomas/kingpin.v2" +) + +// LevelFlagName is the canonical flag name to configure the allowed log level +// within Prometheus projects. +const LevelFlagName = "log.level" + +// LevelFlagHelp is the help description for the log.level flag. +const LevelFlagHelp = "Only log messages with the given severity or above. One of: [debug, info, warn, error]" + +// AddFlags adds the flags used by this package to the Kingpin application. +// To use the default Kingpin application, call AddFlags(kingpin.CommandLine, ..). +func AddFlags(a *kingpin.Application, logLevel *promlog.AllowedLevel) { + a.Flag(LevelFlagName, LevelFlagHelp). + Default("info").SetValue(logLevel) +} diff --git a/vendor/github.com/prometheus/common/promlog/log.go b/vendor/github.com/prometheus/common/promlog/log.go new file mode 100644 index 000000000..cf8307ad2 --- /dev/null +++ b/vendor/github.com/prometheus/common/promlog/log.go @@ -0,0 +1,63 @@ +// Copyright 2017 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 promlog defines standardised ways to initialize Go kit loggers +// across Prometheus components. +// It should typically only ever be imported by main packages. +package promlog + +import ( + "os" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" +) + +// AllowedLevel is a settable identifier for the minimum level a log entry +// must be have. +type AllowedLevel struct { + s string + o level.Option +} + +func (l *AllowedLevel) String() string { + return l.s +} + +// Set updates the value of the allowed level. +func (l *AllowedLevel) Set(s string) error { + switch s { + case "debug": + l.o = level.AllowDebug() + case "info": + l.o = level.AllowInfo() + case "warn": + l.o = level.AllowWarn() + case "error": + l.o = level.AllowError() + default: + return errors.Errorf("unrecognized log level %q", s) + } + l.s = s + return nil +} + +// New returns a new leveled oklog logger in the logfmt format. Each logged line will be annotated +// with a timestamp. The output always goes to stderr. +func New(al AllowedLevel) log.Logger { + l := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) + l = level.NewFilter(l, al.o) + l = log.With(l, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) + return l +} diff --git a/vendor/vendor.json b/vendor/vendor.json index bb499c8b4..8ce00acf8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -422,6 +422,12 @@ "revision": "04dd4f741c6e76cc170a4d7913f4c625952e6f58", "revisionTime": "2017-03-20T09:05:36Z" }, + { + "checksumSHA1": "t7aTpDH0h4BZcGU0KkUr14QQG2w=", + "path": "github.com/go-kit/kit/log/level", + "revision": "6964666de57c88f7d93da127e900d201b632f561", + "revisionTime": "2017-05-17T16:52:12Z" + }, { "checksumSHA1": "KxX/Drph+byPXBFIXaCZaCOAnrU=", "path": "github.com/go-logfmt/logfmt", @@ -840,6 +846,12 @@ "revision": "0d0c3d572886e0f2323ed376557f9eb99b97d25b", "revisionTime": "2017-06-16T14:41:04Z" }, + { + "checksumSHA1": "Yseprf8kAFr/s7wztkQnrFuFN+8=", + "path": "github.com/prometheus/common/promlog", + "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8", + "revisionTime": "2017-09-08T16:18:22Z" + }, { "checksumSHA1": "9aDxDuzZt1l7FQJ9qpn2kPcF7NU=", "path": "github.com/prometheus/common/route",