TrackStarted
// handler是一层包一层,先执行外面的,再执行里面的
// 也就是说先执行TrackStarted, 再执行WithAuthentication
// 开始认证
handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
// 记录身份认证开始时间
handler = filterlatency.TrackStarted(handler, "authentication")
filterlatency.TrackStarted(handler, "authentication")
// TrackStarted measures the timestamp the given handler has started execution
// by attaching a handler to the chain.
func TrackStarted(handler http.Handler, name string) http.Handler {
return trackStarted(handler, name, utilclock.RealClock{})
}
这里有个模式,就是TrackStarted只是透传和添加默认参数,将第一个字母小写trackStarted,才是真正的逻辑。
trackStarted(handler, name, utilclock.RealClock{})
func trackStarted(handler http.Handler, name string, clock utilclock.PassiveClock) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// 从Context中获取requestFilterRecord
if fr := requestFilterRecordFrom(ctx); fr != nil {
fr.name = name
fr.startedTimestamp = clock.Now() // 设置认证开始时间为当前时间
// dispatch to next
handler.ServeHTTP(w, r)
return
}
// 如果没有requestFilterRecord则创建一个
fr := &requestFilterRecord{
name: name,
startedTimestamp: clock.Now(),
}
// + 放到Context中
r = r.WithContext(withRequestFilterRecord(ctx, fr))
handler.ServeHTTP(w, r)
})
}
r = r.WithContext(withRequestFilterRecord(ctx, fr))
// withRequestFilterRecord attaches the given request filter record to the parent context.
func withRequestFilterRecord(parent context.Context, fr *requestFilterRecord) context.Context {
return apirequest.WithValue(parent, requestFilterRecordKey, fr)
}
// WithValue returns a copy of parent in which the value associated with key is val.
func WithValue(parent context.Context, key interface{}, val interface{}) context.Context {
return context.WithValue(parent, key, val)
}
TrackCompleted
记录结束时间,并更新metric数据
// TrackCompleted measures the timestamp the given handler has completed execution and then
// it updates the corresponding metric with the filter latency duration.
func TrackCompleted(handler http.Handler) http.Handler {
return trackCompleted(handler, utilclock.RealClock{}, func(ctx context.Context, fr *requestFilterRecord, completedAt time.Time) {
// 3.2 计算认证耗时,调用prometheus客户端存储
metrics.RecordFilterLatency(ctx, fr.name, completedAt.Sub(fr.startedTimestamp))
})
}
func trackCompleted(handler http.Handler, clock utilclock.PassiveClock, action func(context.Context, *requestFilterRecord, time.Time)) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// The previous filter has just completed.
completedAt := clock.Now() // 1. 认证过程结束,记录时间戳
defer handler.ServeHTTP(w, r) // dispatch next at the end
ctx := r.Context()
// 2. 这里读取开始时间
if fr := requestFilterRecordFrom(ctx); fr != nil {
action(ctx, fr, completedAt) // 3.1 执行传入函数action
}
})
}
metrics.RecordFilterLatency(ctx, fr.name, completedAt.Sub(fr.startedTimestamp))
func RecordFilterLatency(ctx context.Context, name string, elapsed time.Duration) {
requestFilterDuration.WithContext(ctx).WithLabelValues(name).Observe(elapsed.Seconds())
}