@@ -13,20 +13,25 @@ import (
1313 "github.com/free/jiralert/pkg/config"
1414 "github.com/free/jiralert/pkg/notify"
1515 "github.com/free/jiralert/pkg/template"
16+ "github.com/go-kit/kit/log"
17+ "github.com/go-kit/kit/log/level"
1618
1719 _ "net/http/pprof"
1820
19- log "github.com/golang/glog"
2021 "github.com/prometheus/client_golang/prometheus/promhttp"
2122)
2223
2324const (
2425 unknownReceiver = "<unknown>"
26+ logFormatLogfmt = "logfmt"
27+ logFormatJson = "json"
2528)
2629
2730var (
2831 listenAddress = flag .String ("listen-address" , ":9097" , "The address to listen on for HTTP requests." )
2932 configFile = flag .String ("config" , "config/jiralert.yml" , "The JIRAlert configuration file" )
33+ logLevel = flag .String ("log.level" , "info" , "Log filtering level (debug, info, warn, error)" )
34+ logFormat = flag .String ("log.format" , logFormatLogfmt , "Log format to use (" + logFormatLogfmt + ", " + logFormatJson + ")" )
3035
3136 // Version is the build version, set by make to latest git tag/hash via `-ldflags "-X main.Version=$(VERSION)"`.
3237 Version = "<local build>"
@@ -38,64 +43,62 @@ func main() {
3843 runtime .SetMutexProfileFraction (1 )
3944 }
4045
41- // Override -alsologtostderr default value.
42- if alsoLogToStderr := flag .Lookup ("alsologtostderr" ); alsoLogToStderr != nil {
43- alsoLogToStderr .DefValue = "true"
44- alsoLogToStderr .Value .Set ("true" )
45- }
4646 flag .Parse ()
4747
48- log .Infof ("Starting JIRAlert version %s" , Version )
48+ var logger = setupLogger (* logLevel , * logFormat )
49+ level .Info (logger ).Log ("msg" , "starting JIRAlert" , "version" , Version )
4950
50- config , _ , err := config .LoadFile (* configFile )
51+ config , _ , err := config .LoadFile (* configFile , logger )
5152 if err != nil {
52- log .Fatalf ("Error loading configuration: %s" , err )
53+ level .Error (logger ).Log ("msg" , "error loading configuration" , "path" , * configFile , "err" , err )
54+ os .Exit (1 )
5355 }
5456
55- tmpl , err := template .LoadTemplate (config .Template )
57+ tmpl , err := template .LoadTemplate (config .Template , logger )
5658 if err != nil {
57- log .Fatalf ("Error loading templates from %s: %s" , config .Template , err )
59+ level .Error (logger ).Log ("msg" , "error loading templates" , "path" , config .Template , "err" , err )
60+ os .Exit (1 )
5861 }
5962
6063 http .HandleFunc ("/alert" , func (w http.ResponseWriter , req * http.Request ) {
61- log . V ( 1 ). Infof ( "Handling /alert webhook request" )
64+ level . Debug ( logger ). Log ( "msg" , "handling /alert webhook request" )
6265 defer req .Body .Close ()
6366
6467 // https://godoc.org/github.com/prometheus/alertmanager/template#Data
6568 data := alertmanager.Data {}
6669 if err := json .NewDecoder (req .Body ).Decode (& data ); err != nil {
67- errorHandler (w , http .StatusBadRequest , err , unknownReceiver , & data )
70+ errorHandler (w , http .StatusBadRequest , err , unknownReceiver , & data , logger )
6871 return
6972 }
7073
7174 conf := config .ReceiverByName (data .Receiver )
7275 if conf == nil {
73- errorHandler (w , http .StatusNotFound , fmt .Errorf ("receiver missing: %s" , data .Receiver ), unknownReceiver , & data )
76+ errorHandler (w , http .StatusNotFound , fmt .Errorf ("receiver missing: %s" , data .Receiver ), unknownReceiver , & data , logger )
7477 return
7578 }
76- log . V ( 1 ). Infof ( "Matched receiver: %q " , conf .Name )
79+ level . Debug ( logger ). Log ( "msg" , " matched receiver" , "receiver " , conf .Name )
7780
7881 // Filter out resolved alerts, not interested in them.
7982 alerts := data .Alerts .Firing ()
8083 if len (alerts ) < len (data .Alerts ) {
81- log . Warningf ( "Please set \" send_resolved: false\" on receiver %s in the Alertmanager config" , conf .Name )
84+ level . Warn ( logger ). Log ( "msg" , "receiver should have \" send_resolved: false\" set in Alertmanager config" , "receiver " , conf .Name )
8285 data .Alerts = alerts
8386 }
8487
8588 if len (data .Alerts ) > 0 {
8689 r , err := notify .NewReceiver (conf , tmpl )
8790 if err != nil {
88- errorHandler (w , http .StatusInternalServerError , err , conf .Name , & data )
91+ errorHandler (w , http .StatusInternalServerError , err , conf .Name , & data , logger )
8992 return
9093 }
91- if retry , err := r .Notify (& data ); err != nil {
94+ if retry , err := r .Notify (& data , logger ); err != nil {
9295 var status int
9396 if retry {
9497 status = http .StatusServiceUnavailable
9598 } else {
9699 status = http .StatusInternalServerError
97100 }
98- errorHandler (w , status , err , conf .Name , & data )
101+ errorHandler (w , status , err , conf .Name , & data , logger )
99102 return
100103 }
101104 }
@@ -112,11 +115,15 @@ func main() {
112115 * listenAddress = ":" + os .Getenv ("PORT" )
113116 }
114117
115- log .Infof ("Listening on %s" , * listenAddress )
116- log .Fatal (http .ListenAndServe (* listenAddress , nil ))
118+ level .Info (logger ).Log ("msg" , "listening" , "address" , * listenAddress )
119+ err = http .ListenAndServe (* listenAddress , nil )
120+ if err != nil {
121+ level .Error (logger ).Log ("msg" , "failed to start HTTP server" , "address" , * listenAddress )
122+ os .Exit (1 )
123+ }
117124}
118125
119- func errorHandler (w http.ResponseWriter , status int , err error , receiver string , data * alertmanager.Data ) {
126+ func errorHandler (w http.ResponseWriter , status int , err error , receiver string , data * alertmanager.Data , logger log. Logger ) {
120127 w .WriteHeader (status )
121128
122129 response := struct {
@@ -133,6 +140,30 @@ func errorHandler(w http.ResponseWriter, status int, err error, receiver string,
133140 json := string (bytes [:])
134141 fmt .Fprint (w , json )
135142
136- log . Errorf ( "%d %s: err=%s receiver=%q groupLabels=%+v" , status , http .StatusText (status ), err , receiver , data .GroupLabels )
143+ level . Error ( logger ). Log ( "msg" , "error handling request" , "statusCode" , status , "statusText" , http .StatusText (status ), " err" , err , " receiver" , receiver , "groupLabels" , data .GroupLabels )
137144 requestTotal .WithLabelValues (receiver , strconv .FormatInt (int64 (status ), 10 )).Inc ()
138145}
146+
147+ func setupLogger (lvl string , fmt string ) (logger log.Logger ) {
148+ var filter level.Option
149+ switch lvl {
150+ case "error" :
151+ filter = level .AllowError ()
152+ case "warn" :
153+ filter = level .AllowWarn ()
154+ case "debug" :
155+ filter = level .AllowDebug ()
156+ case "info" :
157+ default :
158+ filter = level .AllowInfo ()
159+ }
160+
161+ if fmt == logFormatJson {
162+ logger = log .NewJSONLogger (log .NewSyncWriter (os .Stderr ))
163+ } else {
164+ logger = log .NewLogfmtLogger (log .NewSyncWriter (os .Stderr ))
165+ }
166+ logger = level .NewFilter (logger , filter )
167+ logger = log .With (logger , "ts" , log .DefaultTimestampUTC , "caller" , log .DefaultCaller )
168+ return
169+ }
0 commit comments