Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch logging from glog to go-kit/log #31

Merged
merged 17 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 54 additions & 23 deletions cmd/jiralert/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,25 @@ import (
"github.com/free/jiralert/pkg/config"
"github.com/free/jiralert/pkg/notify"
"github.com/free/jiralert/pkg/template"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"

_ "net/http/pprof"

log "github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

const (
unknownReceiver = "<unknown>"
logFormatLogfmt = "logfmt"
logFormatJson = "json"
)

var (
listenAddress = flag.String("listen-address", ":9097", "The address to listen on for HTTP requests.")
configFile = flag.String("config", "config/jiralert.yml", "The JIRAlert configuration file")
logLevel = flag.String("log.level", "info", "Log filtering level (debug, info, warn, error)")
logFormat = flag.String("log.format", logFormatLogfmt, "Log format to use (" + logFormatLogfmt + ", " + logFormatJson + ")")

// Version is the build version, set by make to latest git tag/hash via `-ldflags "-X main.Version=$(VERSION)"`.
Version = "<local build>"
Expand All @@ -38,64 +43,62 @@ func main() {
runtime.SetMutexProfileFraction(1)
}

// Override -alsologtostderr default value.
if alsoLogToStderr := flag.Lookup("alsologtostderr"); alsoLogToStderr != nil {
alsoLogToStderr.DefValue = "true"
alsoLogToStderr.Value.Set("true")
}
flag.Parse()

log.Infof("Starting JIRAlert version %s", Version)
var logger = setupLogger(*logLevel, *logFormat)
level.Info(logger).Log("msg", "starting JIRAlert", "version", Version)
tdabasinskas marked this conversation as resolved.
Show resolved Hide resolved

config, _, err := config.LoadFile(*configFile)
config, _, err := config.LoadFile(*configFile, logger)
if err != nil {
log.Fatalf("Error loading configuration: %s", err)
level.Error(logger).Log("msg", "error loading configuration", "path", *configFile, "err", err)
os.Exit(1)
}

tmpl, err := template.LoadTemplate(config.Template)
tmpl, err := template.LoadTemplate(config.Template, logger)
if err != nil {
log.Fatalf("Error loading templates from %s: %s", config.Template, err)
level.Error(logger).Log("msg", "error loading templates", "path", config.Template, "err", err)
os.Exit(1)
}

http.HandleFunc("/alert", func(w http.ResponseWriter, req *http.Request) {
log.V(1).Infof("Handling /alert webhook request")
level.Debug(logger).Log("msg", "handling /alert webhook request")
defer req.Body.Close()

// https://godoc.org/github.com/prometheus/alertmanager/template#Data
data := alertmanager.Data{}
if err := json.NewDecoder(req.Body).Decode(&data); err != nil {
errorHandler(w, http.StatusBadRequest, err, unknownReceiver, &data)
errorHandler(w, http.StatusBadRequest, err, unknownReceiver, &data, logger)
return
}

conf := config.ReceiverByName(data.Receiver)
if conf == nil {
errorHandler(w, http.StatusNotFound, fmt.Errorf("receiver missing: %s", data.Receiver), unknownReceiver, &data)
errorHandler(w, http.StatusNotFound, fmt.Errorf("receiver missing: %s", data.Receiver), unknownReceiver, &data, logger)
return
}
log.V(1).Infof("Matched receiver: %q", conf.Name)
level.Debug(logger).Log("msg", " matched receiver", "receiver", conf.Name)

// Filter out resolved alerts, not interested in them.
alerts := data.Alerts.Firing()
if len(alerts) < len(data.Alerts) {
log.Warningf("Please set \"send_resolved: false\" on receiver %s in the Alertmanager config", conf.Name)
level.Warn(logger).Log("msg", "receiver should have \"send_resolved: false\" set in Alertmanager config", "receiver", conf.Name)
data.Alerts = alerts
}

if len(data.Alerts) > 0 {
r, err := notify.NewReceiver(conf, tmpl)
if err != nil {
errorHandler(w, http.StatusInternalServerError, err, conf.Name, &data)
errorHandler(w, http.StatusInternalServerError, err, conf.Name, &data, logger)
return
}
if retry, err := r.Notify(&data); err != nil {
if retry, err := r.Notify(&data, logger); err != nil {
var status int
if retry {
status = http.StatusServiceUnavailable
} else {
status = http.StatusInternalServerError
}
errorHandler(w, status, err, conf.Name, &data)
errorHandler(w, status, err, conf.Name, &data, logger)
return
}
}
Expand All @@ -112,11 +115,15 @@ func main() {
*listenAddress = ":" + os.Getenv("PORT")
}

log.Infof("Listening on %s", *listenAddress)
log.Fatal(http.ListenAndServe(*listenAddress, nil))
level.Info(logger).Log("msg", "listening", "address", *listenAddress)
err = http.ListenAndServe(*listenAddress, nil)
if err != nil {
level.Error(logger).Log("msg", "failed to start HTTP server", "address", *listenAddress)
os.Exit(1)
tdabasinskas marked this conversation as resolved.
Show resolved Hide resolved
}
}

func errorHandler(w http.ResponseWriter, status int, err error, receiver string, data *alertmanager.Data) {
func errorHandler(w http.ResponseWriter, status int, err error, receiver string, data *alertmanager.Data, logger log.Logger) {
w.WriteHeader(status)

response := struct {
Expand All @@ -133,6 +140,30 @@ func errorHandler(w http.ResponseWriter, status int, err error, receiver string,
json := string(bytes[:])
fmt.Fprint(w, json)

log.Errorf("%d %s: err=%s receiver=%q groupLabels=%+v", status, http.StatusText(status), err, receiver, data.GroupLabels)
level.Error(logger).Log("msg", "error handling request", "statusCode", status, "statusText", http.StatusText(status), "err", err, "receiver", receiver, "groupLabels", data.GroupLabels)
requestTotal.WithLabelValues(receiver, strconv.FormatInt(int64(status), 10)).Inc()
}

func setupLogger(lvl string, fmt string) (logger log.Logger) {
var filter level.Option
switch lvl {
case "error":
filter = level.AllowError()
case "warn":
filter = level.AllowWarn()
case "debug":
filter = level.AllowDebug()
case "info":
default:
filter = level.AllowInfo()
}

if fmt == logFormatJson {
logger = log.NewJSONLogger(log.NewSyncWriter(os.Stderr))
} else {
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
}
logger = level.NewFilter(logger, filter)
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
return
}
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ require (
github.com/andygrunwald/go-jira v0.0.0-20181018203616-bbce4afa5493
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a // indirect
github.com/fatih/structs v0.0.0-20171020064819-f5faa72e7309 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/go-kit/kit v0.8.0
github.com/go-logfmt/logfmt v0.4.0 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/golang/protobuf v0.0.0-20171021043952-1643683e1b54 // indirect
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 // indirect
github.com/kr/pretty v0.1.0 // indirect
Expand All @@ -16,7 +18,6 @@ require (
github.com/prometheus/procfs v0.0.0-20171017214025-a6e9df898b13 // indirect
github.com/trivago/tgo v1.0.1
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect
golang.org/x/tools v0.0.0-20190315214010-f0bfdbff1f9c // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7
)
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a h1:BtpsbiV638WQZwhA98
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/fatih/structs v0.0.0-20171020064819-f5faa72e7309 h1:yetGKN1jYaaVt+q69KPz+V2Z64OyTw/KfTNQS90n/tU=
github.com/fatih/structs v0.0.0-20171020064819-f5faa72e7309/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/golang/protobuf v0.0.0-20171021043952-1643683e1b54 h1:nRNJXiJvemchkOTn0V4U11TZkvacB94gTzbTZbSA7Rw=
github.com/golang/protobuf v0.0.0-20171021043952-1643683e1b54/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand All @@ -29,14 +35,8 @@ github.com/prometheus/procfs v0.0.0-20171017214025-a6e9df898b13 h1:leRfx9kcgnSDk
github.com/prometheus/procfs v0.0.0-20171017214025-a6e9df898b13/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/trivago/tgo v1.0.1 h1:bxatjJIXNIpV18bucU4Uk/LaoxvxuOlp/oowRHyncLQ=
github.com/trivago/tgo v1.0.1/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190315214010-f0bfdbff1f9c h1:KQ2sRfnx/Xk0E4v13yE9v3gCXAn6qieU1aiQOsbmpQg=
golang.org/x/tools v0.0.0-20190315214010-f0bfdbff1f9c/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7 h1:+t9dhfO+GNOIGJof6kPOAenx7YgrZMTdRPV+EsnPabk=
Expand Down
14 changes: 7 additions & 7 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package config

import (
"fmt"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"io/ioutil"
"net/url"
"path/filepath"
Expand All @@ -10,7 +12,6 @@ import (
"strings"
"time"

log "github.com/golang/glog"
"github.com/trivago/tgo/tcontainer"
"gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -39,13 +40,12 @@ func Load(s string) (*Config, error) {
if err != nil {
return nil, err
}
log.V(1).Infof("Loaded config:\n%+v", cfg)
return cfg, nil
}

// LoadFile parses the given YAML file into a Config.
func LoadFile(filename string) (*Config, []byte, error) {
log.V(1).Infof("Loading configuration from %q", filename)
func LoadFile(filename string, logger log.Logger) (*Config, []byte, error) {
level.Info(logger).Log("msg", "loading configuration", "path", filename)
content, err := ioutil.ReadFile(filename)
if err != nil {
return nil, nil, err
Expand All @@ -55,19 +55,19 @@ func LoadFile(filename string) (*Config, []byte, error) {
return nil, nil, err
}

resolveFilepaths(filepath.Dir(filename), cfg)
resolveFilepaths(filepath.Dir(filename), cfg, logger)
return cfg, content, nil
}

// resolveFilepaths joins all relative paths in a configuration
// with a given base directory.
func resolveFilepaths(baseDir string, cfg *Config) {
func resolveFilepaths(baseDir string, cfg *Config, logger log.Logger) {
join := func(fp string) string {
if len(fp) == 0 || filepath.IsAbs(fp) {
return fp
}
absFp := filepath.Join(baseDir, fp)
log.V(2).Infof("Relative path %q resolved to %q", fp, absFp)
level.Debug(logger).Log("msg", "resolved relative configuration path", "relativePath", fp, "absolutePath", absFp)
return absFp
}

Expand Down
Loading