Skip to content

Commit 3c04760

Browse files
authored
Merge pull request kubernetes#86265 from mikedanese/cachestats
auth: add metrics to token cache
2 parents e1c7112 + 3f3bc37 commit 3c04760

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

staging/src/k8s.io/apiserver/pkg/authentication/token/cache/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ go_library(
2929
"cache_simple.go",
3030
"cache_striped.go",
3131
"cached_token_authenticator.go",
32+
"stats.go",
3233
],
3334
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/authentication/token/cache",
3435
importpath = "k8s.io/apiserver/pkg/authentication/token/cache",
@@ -37,6 +38,8 @@ go_library(
3738
"//staging/src/k8s.io/apimachinery/pkg/util/cache:go_default_library",
3839
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
3940
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
41+
"//staging/src/k8s.io/component-base/metrics:go_default_library",
42+
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
4043
"//vendor/golang.org/x/sync/singleflight:go_default_library",
4144
"//vendor/k8s.io/klog:go_default_library",
4245
],

staging/src/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,29 @@ func newWithClock(authenticator authenticator.Token, cacheErrs bool, successTTL,
109109

110110
// AuthenticateToken implements authenticator.Token
111111
func (a *cachedTokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) {
112+
doneAuthenticating := stats.authenticating()
113+
112114
auds, audsOk := authenticator.AudiencesFrom(ctx)
113115

114116
key := keyFunc(a.hashPool, auds, token)
115117
if record, ok := a.cache.get(key); ok {
118+
// Record cache hit
119+
doneAuthenticating(true)
116120
return record.resp, record.ok, record.err
117121
}
118122

123+
// Record cache miss
124+
doneBlocking := stats.blocking()
125+
defer doneBlocking()
126+
defer doneAuthenticating(false)
127+
119128
type lookup struct {
120129
resp *authenticator.Response
121130
ok bool
122131
}
123132

124133
c := a.group.DoChan(key, func() (val interface{}, err error) {
134+
doneFetching := stats.fetching()
125135
// We're leaving the request handling stack so we need to handle crashes
126136
// ourselves. Log a stack trace and return a 500 if something panics.
127137
defer func() {
@@ -134,6 +144,7 @@ func (a *cachedTokenAuthenticator) AuthenticateToken(ctx context.Context, token
134144
buf = buf[:runtime.Stack(buf, false)]
135145
klog.Errorf("%v\n%s", r, buf)
136146
}
147+
doneFetching(err == nil)
137148
}()
138149

139150
// Check again for a cached record. We may have raced with a fetch.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
Copyright 2019 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cache
18+
19+
import (
20+
"time"
21+
22+
"k8s.io/component-base/metrics"
23+
"k8s.io/component-base/metrics/legacyregistry"
24+
)
25+
26+
var (
27+
requestLatency = metrics.NewHistogramVec(
28+
&metrics.HistogramOpts{
29+
Namespace: "authentication",
30+
Subsystem: "token_cache",
31+
Name: "request_duration_seconds",
32+
StabilityLevel: metrics.ALPHA,
33+
},
34+
[]string{"status"},
35+
)
36+
requestCount = metrics.NewCounterVec(
37+
&metrics.CounterOpts{
38+
Namespace: "authentication",
39+
Subsystem: "token_cache",
40+
Name: "request_count",
41+
StabilityLevel: metrics.ALPHA,
42+
},
43+
[]string{"status"},
44+
)
45+
fetchCount = metrics.NewGaugeVec(
46+
&metrics.GaugeOpts{
47+
Namespace: "authentication",
48+
Subsystem: "token_cache",
49+
Name: "fetch_count",
50+
StabilityLevel: metrics.ALPHA,
51+
},
52+
[]string{"status"},
53+
)
54+
blockCount = metrics.NewGauge(
55+
&metrics.GaugeOpts{
56+
Namespace: "authentication",
57+
Subsystem: "token_cache",
58+
Name: "block_count",
59+
StabilityLevel: metrics.ALPHA,
60+
},
61+
)
62+
)
63+
64+
func init() {
65+
legacyregistry.MustRegister(
66+
requestLatency,
67+
requestCount,
68+
fetchCount,
69+
blockCount,
70+
)
71+
}
72+
73+
const (
74+
hitTag = "hit"
75+
missTag = "miss"
76+
77+
fetchActiveTag = "active"
78+
fetchFailedTag = "error"
79+
fetchOkTag = "ok"
80+
)
81+
82+
type statsCollector struct{}
83+
84+
var stats = statsCollector{}
85+
86+
func (statsCollector) authenticating() func(hit bool) {
87+
start := time.Now()
88+
return func(hit bool) {
89+
var tag string
90+
if hit {
91+
tag = hitTag
92+
} else {
93+
tag = missTag
94+
}
95+
96+
latency := time.Since(start)
97+
98+
requestCount.WithLabelValues(tag).Inc()
99+
requestLatency.WithLabelValues(tag).Observe(float64(latency.Milliseconds()) / 1000)
100+
}
101+
}
102+
103+
func (statsCollector) blocking() func() {
104+
blockCount.Inc()
105+
return blockCount.Dec
106+
}
107+
108+
func (statsCollector) fetching() func(ok bool) {
109+
fetchCount.WithLabelValues(fetchActiveTag).Inc()
110+
return func(ok bool) {
111+
var tag string
112+
if ok {
113+
tag = fetchOkTag
114+
} else {
115+
tag = fetchFailedTag
116+
}
117+
118+
fetchCount.WithLabelValues(tag).Dec()
119+
}
120+
}

0 commit comments

Comments
 (0)