Skip to content
This repository was archived by the owner on Jun 12, 2025. It is now read-only.

Commit 73aa986

Browse files
committed
Add metrics exporter
1 parent 1e811bc commit 73aa986

File tree

5 files changed

+85
-7
lines changed

5 files changed

+85
-7
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
*~
22
bin
33
vendor
4-
./idea
4+
.idea
55
*.iml

dex-auth.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ func (config *Config) handleIndex(w http.ResponseWriter, r *http.Request) {
2929
renderIndex(w, config)
3030
}
3131

32+
func (config *Config) handleHealthz(w http.ResponseWriter, r *http.Request) {
33+
w.Header().Set("Content-Type", "application/json")
34+
w.WriteHeader(http.StatusOK)
35+
if _, err := w.Write([]byte(`{"status": "ok"}`)); err != nil {
36+
log.Printf("error in response writing: %#v", err)
37+
}
38+
}
39+
3240
func (cluster *Cluster) handleLogin(w http.ResponseWriter, r *http.Request) {
3341
var scopes []string
3442

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/AnchorFree/dex-k8s-authenticator
33
require (
44
github.com/coreos/go-oidc v2.0.0+incompatible
55
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
6+
github.com/prometheus/client_golang v0.9.2
67
github.com/spf13/cobra v0.0.3
78
github.com/spf13/viper v1.3.1
89
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 // indirect

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
2+
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
3+
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
24
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
35
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
46
github.com/coreos/go-oidc v2.0.0+incompatible h1:+RStIopZ8wooMx+Vs5Bt8zMXxV1ABl5LbakNExNmZIg=
@@ -7,17 +9,29 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
79
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
810
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
911
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
12+
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
13+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
1014
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
1115
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
1216
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
1317
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
18+
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
19+
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
1420
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
1521
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
1622
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
1723
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
1824
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1925
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
2026
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
27+
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
28+
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
29+
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
30+
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
31+
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
32+
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
33+
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
34+
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
2135
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
2236
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
2337
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
@@ -35,10 +49,12 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT
3549
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
3650
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
3751
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
52+
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
3853
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
3954
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
4055
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
4156
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
57+
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4258
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
4359
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
4460
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=

main.go

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"crypto/tls"
77
"crypto/x509"
88
"fmt"
9+
"github.com/prometheus/client_golang/prometheus"
10+
"github.com/prometheus/client_golang/prometheus/promauto"
11+
"github.com/prometheus/client_golang/prometheus/promhttp"
912
"io/ioutil"
1013
"log"
1114
"net/http"
@@ -138,6 +141,24 @@ func start_app(config Config) {
138141
config.Web_Path_Prefix = web_path_prefix
139142
}
140143

144+
// Counter for login requests
145+
loginCounter := promauto.NewCounterVec(
146+
prometheus.CounterOpts{
147+
Name: "dex_k8s_authenticator_login_requests_total",
148+
Help: "Total number of login requests by HTTP status code, method and cluster.",
149+
},
150+
[]string{"code", "cluster"},
151+
)
152+
153+
// Counter for callback response
154+
callbackCounter := promauto.NewCounterVec(
155+
prometheus.CounterOpts{
156+
Name: "dex_k8s_authenticator_callback_response_total",
157+
Help: "Total number of callback response by HTTP status code, method and cluster.",
158+
},
159+
[]string{"code", "cluster"},
160+
)
161+
141162
// Generate handlers for each cluster
142163
for i, _ := range config.Clusters {
143164
cluster := config.Clusters[i]
@@ -199,24 +220,57 @@ func start_app(config Config) {
199220
os.Exit(1)
200221
}
201222

202-
// Each cluster gets a different login and callback URL
203-
http.HandleFunc(base_redirect_uri.Path, cluster.handleCallback)
223+
// Cluster Label for Metrics
224+
clusterLabel := prometheus.Labels{"cluster": cluster.Name}
225+
226+
// Each cluster gets a different callback URL
227+
http.HandleFunc(base_redirect_uri.Path,
228+
promhttp.InstrumentHandlerCounter(
229+
loginCounter.MustCurryWith(clusterLabel),
230+
http.HandlerFunc(cluster.handleCallback),
231+
),
232+
)
204233
log.Printf("Registered callback handler at: %s", base_redirect_uri.Path)
205234

235+
// Each cluster gets a different login URL
206236
login_uri := path.Join(config.Web_Path_Prefix, "login", cluster.Name)
207-
http.HandleFunc(login_uri, cluster.handleLogin)
237+
http.HandleFunc(login_uri,
238+
promhttp.InstrumentHandlerCounter(
239+
callbackCounter.MustCurryWith(clusterLabel),
240+
http.HandlerFunc(cluster.handleLogin),
241+
),
242+
)
208243
log.Printf("Registered login handler at: %s", login_uri)
209244
}
210245

211246
// Index page
212-
http.HandleFunc(config.Web_Path_Prefix, config.handleIndex)
247+
indexHandler := promhttp.InstrumentHandlerCounter(
248+
promauto.NewCounterVec(
249+
prometheus.CounterOpts{
250+
Name: "dex_k8s_authenticator_index_requests_total",
251+
Help: "Total number of index requests by HTTP status code.",
252+
},
253+
[]string{"code", "method"},
254+
),
255+
http.HandlerFunc(config.handleIndex),
256+
)
257+
http.HandleFunc(config.Web_Path_Prefix, indexHandler)
258+
log.Printf("Registered index handler at: %s", config.Web_Path_Prefix)
213259

214260
// Serve static html assets
215261
fs := http.FileServer(http.Dir("html/static/"))
216262
static_uri := path.Join(config.Web_Path_Prefix, "static") + "/"
263+
http.Handle(static_uri, http.StripPrefix(static_uri, fs))
217264
log.Printf("Registered static assets handler at: %s", static_uri)
218265

219-
http.Handle(static_uri, http.StripPrefix(static_uri, fs))
266+
// Export metrics for prometheus
267+
http.Handle("/metrics", promhttp.Handler())
268+
log.Printf("Registered metrics handler at: %s", "/metrics")
269+
270+
// Register health check endpoint
271+
healthzPattern := path.Join(config.Web_Path_Prefix, "healthz")
272+
http.HandleFunc(healthzPattern, config.handleHealthz)
273+
log.Printf("Registered healthz handler at: %s", healthzPattern)
220274

221275
// Determine whether to use TLS or not
222276
switch listenURL.Scheme {
@@ -302,7 +356,6 @@ var RootCmd = &cobra.Command{
302356

303357
// Fallback if no args specified
304358
cmd.HelpFunc()(cmd, args)
305-
306359
},
307360
}
308361

0 commit comments

Comments
 (0)