From 551f355dc34de84a6857a64483e78f08a869c85e Mon Sep 17 00:00:00 2001 From: Alex Yu Date: Tue, 22 May 2018 01:05:29 -0400 Subject: [PATCH] promlog: add support for json logger Fixes issue: https://github.com/prometheus/prometheus/issues/3219 Signed-off-by: Alex Yu --- promlog/flag/flag.go | 14 ++++++++++++-- promlog/log.go | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/promlog/flag/flag.go b/promlog/flag/flag.go index b9d361e4..28c88ea7 100644 --- a/promlog/flag/flag.go +++ b/promlog/flag/flag.go @@ -25,9 +25,19 @@ 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]" +// FormatFlagName is the canonical flag name to configure the log format +// within Prometheus projects. +const FormatFlagName = "log.format" + +// FormatFlagHelp is the help description for the log.format flag. +const FormatFlagHelp = "Output format of log messages. One of: [logfmt, json]" + // 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) { +func AddFlags(a *kingpin.Application, config *promlog.Config) { a.Flag(LevelFlagName, LevelFlagHelp). - Default("info").SetValue(logLevel) + Default("info").SetValue(config.Level) + + a.Flag(FormatFlagName, FormatFlagHelp). + Default("logfmt").SetValue(config.Format) } diff --git a/promlog/log.go b/promlog/log.go index cf8307ad..a631a133 100644 --- a/promlog/log.go +++ b/promlog/log.go @@ -53,11 +53,42 @@ func (l *AllowedLevel) Set(s string) error { return nil } -// New returns a new leveled oklog logger in the logfmt format. Each logged line will be annotated +// AllowedFormat is a settable identifier for the output format that the logger can have. +type AllowedFormat struct { + s string +} + +func (f *AllowedFormat) String() string { + return f.s +} + +// Set updates the value of the allowed format. +func (f *AllowedFormat) Set(s string) error { + switch s { + case "logfmt", "json": + f.s = s + default: + return errors.Errorf("unrecognized log format %q", s) + } + return nil +} + +type Config struct { + Level *AllowedLevel + Format *AllowedFormat +} + +// New returns a new leveled oklog logger. 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) +func New(config *Config) log.Logger { + var l log.Logger + if config.Format.s == "logfmt" { + l = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) + } else { + l = log.NewJSONLogger(log.NewSyncWriter(os.Stderr)) + } + + l = level.NewFilter(l, config.Level.o) l = log.With(l, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) return l }