github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/runner/jujuc/add-metric.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "fmt" 8 "strings" 9 "time" 10 11 "github.com/juju/cmd" 12 "github.com/juju/errors" 13 "github.com/juju/gnuflag" 14 "github.com/juju/utils/keyvalues" 15 "gopkg.in/juju/charm.v6" 16 17 jujucmd "github.com/juju/juju/cmd" 18 ) 19 20 // Metric represents a single metric set by the charm. 21 type Metric struct { 22 Key string 23 Value string 24 Time time.Time 25 Labels map[string]string `json:",omitempty"` 26 } 27 28 // AddMetricCommand implements the add-metric command. 29 type AddMetricCommand struct { 30 cmd.CommandBase 31 ctx Context 32 Labels string 33 Metrics []Metric 34 } 35 36 // NewAddMetricCommand generates a new AddMetricCommand. 37 func NewAddMetricCommand(ctx Context) (cmd.Command, error) { 38 return &AddMetricCommand{ctx: ctx}, nil 39 } 40 41 // Info returns the command info structure for the add-metric command. 42 func (c *AddMetricCommand) Info() *cmd.Info { 43 return jujucmd.Info(&cmd.Info{ 44 Name: "add-metric", 45 Args: "key1=value1 [key2=value2 ...]", 46 Purpose: "add metrics", 47 }) 48 } 49 50 // SetFlags implements Command. 51 func (c *AddMetricCommand) SetFlags(f *gnuflag.FlagSet) { 52 f.StringVar(&c.Labels, "l", "", "labels to be associated with metric values") 53 f.StringVar(&c.Labels, "labels", "", "") 54 } 55 56 // Init parses the command's parameters. 57 func (c *AddMetricCommand) Init(args []string) error { 58 // TODO(fwereade): 2016-03-17 lp:1558657 59 now := time.Now() 60 if len(args) == 0 { 61 return fmt.Errorf("no metrics specified") 62 } 63 kvs, err := keyvalues.Parse(args, false) 64 if err != nil { 65 return errors.Annotate(err, "invalid metrics") 66 } 67 var labelArgs []string 68 if c.Labels != "" { 69 labelArgs = strings.Split(c.Labels, ",") 70 } 71 for key, value := range kvs { 72 labels, err := keyvalues.Parse(labelArgs, false) 73 if err != nil { 74 return errors.Annotate(err, "invalid labels") 75 } 76 c.Metrics = append(c.Metrics, Metric{ 77 Key: key, 78 Value: value, 79 Time: now, 80 Labels: labels, 81 }) 82 } 83 return nil 84 } 85 86 // Run adds metrics to the hook context. 87 func (c *AddMetricCommand) Run(ctx *cmd.Context) (err error) { 88 for _, metric := range c.Metrics { 89 if charm.IsBuiltinMetric(metric.Key) { 90 return errors.Errorf("%v uses a reserved prefix", metric.Key) 91 } 92 if len(metric.Labels) > 0 { 93 err := c.ctx.AddMetricLabels(metric.Key, metric.Value, metric.Time, metric.Labels) 94 if err != nil { 95 return errors.Annotate(err, "cannot record metric") 96 } 97 } else { 98 err := c.ctx.AddMetric(metric.Key, metric.Value, metric.Time) 99 if err != nil { 100 return errors.Annotate(err, "cannot record metric") 101 } 102 } 103 } 104 return nil 105 }