1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the LGPLv3, see LICENCE file for details.
12
goyaml "gopkg.in/yaml.v1"
15
// MetricType is used to identify metric types supported by juju.
16
type MetricType string
19
// Supported metric types.
20
MetricTypeGauge MetricType = "gauge"
21
MetricTypeAbsolute MetricType = "absolute"
24
// validateValue checks if the supplied metric value fits the requirements
25
// of its expected type.
26
func (m MetricType) validateValue(value string) error {
28
case MetricTypeGauge, MetricTypeAbsolute:
29
// The largest number of digits that can be returned by strconv.FormatFloat is 24, so
30
// choose an arbitrary limit somewhat higher than that.
32
return fmt.Errorf("metric value is too large")
34
_, err := strconv.ParseFloat(value, 64)
36
return fmt.Errorf("invalid value type: expected float, got %q", value)
39
return fmt.Errorf("unknown metric type %q", m)
44
// Metric represents a single metric definition
50
// Metrics contains the metrics declarations encoded in the metrics.yaml
53
Metrics map[string]Metric
56
// ReadMetrics reads a MetricsDeclaration in YAML format.
57
func ReadMetrics(r io.Reader) (*Metrics, error) {
58
data, err := ioutil.ReadAll(r)
63
if err := goyaml.Unmarshal(data, &metrics); err != nil {
66
if metrics.Metrics == nil {
69
for name, metric := range metrics.Metrics {
71
case MetricTypeGauge, MetricTypeAbsolute:
73
return nil, fmt.Errorf("invalid metrics declaration: metric %q has unknown type %q", name, metric.Type)
75
if metric.Description == "" {
76
return nil, fmt.Errorf("invalid metrics declaration: metric %q lacks description", name)
82
// ValidateMetric validates the supplied metric name and value against the loaded
83
// metric definitions.
84
func (m Metrics) ValidateMetric(name, value string) error {
85
metric, exists := m.Metrics[name]
87
return fmt.Errorf("metric %q not defined", name)
89
return metric.Type.validateValue(value)