From a1b2fcb10fd34af382138a1f45ec8c4342ee9523 Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Fri, 9 Sep 2016 11:25:09 +1000 Subject: [PATCH] Disambiguate unsupported metrics from metrics errors --- .../server/stats/volume_stat_calculator.go | 6 +- pkg/volume/metrics_du.go | 7 +- pkg/volume/metrics_errors.go | 77 +++++++++++++++++++ pkg/volume/metrics_nil.go | 4 +- pkg/volume/metrics_statfs.go | 7 +- 5 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 pkg/volume/metrics_errors.go diff --git a/pkg/kubelet/server/stats/volume_stat_calculator.go b/pkg/kubelet/server/stats/volume_stat_calculator.go index 8cdc9f4ea5..34e47b04d7 100644 --- a/pkg/kubelet/server/stats/volume_stat_calculator.go +++ b/pkg/kubelet/server/stats/volume_stat_calculator.go @@ -98,9 +98,9 @@ func (s *volumeStatCalculator) calcAndStoreStats() { metric, err := v.GetMetrics() if err != nil { // Expected for Volumes that don't support Metrics - // TODO: Disambiguate unsupported from errors - // See issue #20676 - glog.V(4).Infof("Failed to calculate volume metrics for pod %s volume %s: %+v", format.Pod(s.pod), name, err) + if !volume.IsNotSupported(err) { + glog.V(4).Infof("Failed to calculate volume metrics for pod %s volume %s: %+v", format.Pod(s.pod), name, err) + } continue } stats = append(stats, s.parsePodVolumeStats(name, metric)) diff --git a/pkg/volume/metrics_du.go b/pkg/volume/metrics_du.go index 95d24caecc..38cc209028 100644 --- a/pkg/volume/metrics_du.go +++ b/pkg/volume/metrics_du.go @@ -17,9 +17,6 @@ limitations under the License. package volume import ( - "errors" - "fmt" - "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/volume/util" ) @@ -45,7 +42,7 @@ func NewMetricsDu(path string) MetricsProvider { func (md *metricsDu) GetMetrics() (*Metrics, error) { metrics := &Metrics{} if md.path == "" { - return metrics, errors.New("no path defined for disk usage metrics.") + return metrics, NewNoPathDefinedError() } err := md.runDu(metrics) @@ -76,7 +73,7 @@ func (md *metricsDu) runDu(metrics *Metrics) error { func (md *metricsDu) getFsInfo(metrics *Metrics) error { available, capacity, _, err := util.FsInfo(md.path) if err != nil { - return fmt.Errorf("Failed to get FsInfo due to error %v", err) + return NewFsInfoFailedError(err) } metrics.Available = resource.NewQuantity(available, resource.BinarySI) metrics.Capacity = resource.NewQuantity(capacity, resource.BinarySI) diff --git a/pkg/volume/metrics_errors.go b/pkg/volume/metrics_errors.go new file mode 100644 index 0000000000..50e7c2a21b --- /dev/null +++ b/pkg/volume/metrics_errors.go @@ -0,0 +1,77 @@ +/* +Copyright 2016 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 volume + +import ( + "fmt" +) + +const ( + // ErrCodeNotSupported code for NotSupported Errors. + ErrCodeNotSupported int = iota + 1 + ErrCodeNoPathDefined + ErrCodeFsInfoFailed +) + +// NewNotSupportedError creates a new MetricsError with code NotSupported. +func NewNotSupportedError() *MetricsError { + return &MetricsError{ + Code: ErrCodeNotSupported, + Msg: "metrics are not supported for MetricsNil Volumes", + } +} + +// NewNoPathDefined creates a new MetricsError with code NoPathDefined. +func NewNoPathDefinedError() *MetricsError { + return &MetricsError{ + Code: ErrCodeNoPathDefined, + Msg: "no path defined for disk usage metrics.", + } +} + +// NewFsInfoFailedError creates a new MetricsError with code FsInfoFailed. +func NewFsInfoFailedError(err error) *MetricsError { + return &MetricsError{ + Code: ErrCodeFsInfoFailed, + Msg: fmt.Sprintf("Failed to get FsInfo due to error %v", err), + } +} + +// MetricsError to distinguish different Metrics Errors. +type MetricsError struct { + Code int + Msg string +} + +func (e *MetricsError) Error() string { + return fmt.Sprintf("%s", e.Msg) +} + +// IsNotSupported returns true if and only if err is "key" not found error. +func IsNotSupported(err error) bool { + return isErrCode(err, ErrCodeNotSupported) +} + +func isErrCode(err error, code int) bool { + if err == nil { + return false + } + if e, ok := err.(*MetricsError); ok { + return e.Code == code + } + return false +} diff --git a/pkg/volume/metrics_nil.go b/pkg/volume/metrics_nil.go index 38b81fcd74..5438dc3de3 100644 --- a/pkg/volume/metrics_nil.go +++ b/pkg/volume/metrics_nil.go @@ -16,8 +16,6 @@ limitations under the License. package volume -import "errors" - var _ MetricsProvider = &MetricsNil{} // MetricsNil represents a MetricsProvider that does not support returning @@ -28,5 +26,5 @@ type MetricsNil struct{} // GetMetrics returns an empty Metrics and an error. // See MetricsProvider.GetMetrics func (*MetricsNil) GetMetrics() (*Metrics, error) { - return &Metrics{}, errors.New("metrics are not supported for MetricsNil Volumes") + return &Metrics{}, NewNotSupportedError() } diff --git a/pkg/volume/metrics_statfs.go b/pkg/volume/metrics_statfs.go index d98d36b81f..ec2d64ea63 100644 --- a/pkg/volume/metrics_statfs.go +++ b/pkg/volume/metrics_statfs.go @@ -17,9 +17,6 @@ limitations under the License. package volume import ( - "errors" - "fmt" - "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/volume/util" ) @@ -44,7 +41,7 @@ func NewMetricsStatFS(path string) MetricsProvider { func (md *metricsStatFS) GetMetrics() (*Metrics, error) { metrics := &Metrics{} if md.path == "" { - return metrics, errors.New("no path defined for disk usage metrics.") + return metrics, NewNoPathDefinedError() } err := md.getFsInfo(metrics) @@ -59,7 +56,7 @@ func (md *metricsStatFS) GetMetrics() (*Metrics, error) { func (md *metricsStatFS) getFsInfo(metrics *Metrics) error { available, capacity, usage, err := util.FsInfo(md.path) if err != nil { - return fmt.Errorf("Failed to get FsInfo due to error %v", err) + return NewFsInfoFailedError(err) } metrics.Available = resource.NewQuantity(available, resource.BinarySI) metrics.Capacity = resource.NewQuantity(capacity, resource.BinarySI)