logging: Port to common/promlog

Signed-off-by: Goutham Veeramachaneni <cs14btech11014@iith.ac.in>
This commit is contained in:
Goutham Veeramachaneni 2017-09-08 22:04:20 +05:30
parent d21f149745
commit f5aed810f9
11 changed files with 356 additions and 20 deletions

View file

@ -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)

View file

@ -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),

View file

@ -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() {

View file

@ -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}
}

View file

@ -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)

View file

@ -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
}

22
vendor/github.com/go-kit/kit/log/level/doc.go generated vendored Normal file
View file

@ -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

205
vendor/github.com/go-kit/kit/log/level/level.go generated vendored Normal file
View file

@ -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() {}

View file

@ -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)
}

63
vendor/github.com/prometheus/common/promlog/log.go generated vendored Normal file
View file

@ -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
}

12
vendor/vendor.json vendored
View file

@ -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",