From 959ee35394452dd88a07b3e2c389f8e3aaf0aa8c Mon Sep 17 00:00:00 2001 From: immutablet Date: Tue, 27 Feb 2018 17:24:27 -0800 Subject: [PATCH] Instrument transformer.go with latency metrics. Kubernetes-commit: e54864f53de75cd56c0fe94777e1d3de0c559c7f --- pkg/storage/value/metrics.go | 55 ++++++++++++++++++++++++++++++++ pkg/storage/value/transformer.go | 7 ++++ 2 files changed, 62 insertions(+) create mode 100644 pkg/storage/value/metrics.go diff --git a/pkg/storage/value/metrics.go b/pkg/storage/value/metrics.go new file mode 100644 index 000000000..1cdb006a4 --- /dev/null +++ b/pkg/storage/value/metrics.go @@ -0,0 +1,55 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" +) + +const ( + valueSubsystem = "value" +) + +var ( + TransformerOperationalLatencies = prometheus.NewSummaryVec( + prometheus.SummaryOpts{ + Subsystem: valueSubsystem, + Name: "storage_transformation_latency_microseconds", + Help: "Latency in microseconds of value transformation operations.", + }, + []string{"transformation_type"}, + ) +) + +var registerMetrics sync.Once + +func RegisterMetrics() { + registerMetrics.Do(func() { + prometheus.MustRegister(TransformerOperationalLatencies) + }) +} + +func RecordTransformation(transformationType string, start time.Time) { + TransformerOperationalLatencies.WithLabelValues(transformationType).Observe(sinceInMicroseconds(start)) +} + +func sinceInMicroseconds(start time.Time) float64 { + return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds()) +} diff --git a/pkg/storage/value/transformer.go b/pkg/storage/value/transformer.go index 04af5d6db..899814716 100644 --- a/pkg/storage/value/transformer.go +++ b/pkg/storage/value/transformer.go @@ -21,8 +21,13 @@ import ( "bytes" "fmt" "sync" + "time" ) +func init() { + RegisterMetrics() +} + // Context is additional information that a storage transformation may need to verify the data at rest. type Context interface { // AuthenticatedData should return an array of bytes that describes the current value. If the value changes, @@ -80,12 +85,14 @@ func (t *MutableTransformer) Set(transformer Transformer) { } func (t *MutableTransformer) TransformFromStorage(data []byte, context Context) (out []byte, stale bool, err error) { + defer RecordTransformation("from_storage", time.Now()) t.lock.RLock() transformer := t.transformer t.lock.RUnlock() return transformer.TransformFromStorage(data, context) } func (t *MutableTransformer) TransformToStorage(data []byte, context Context) (out []byte, err error) { + defer RecordTransformation("to_storage", time.Now()) t.lock.RLock() transformer := t.transformer t.lock.RUnlock()