github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/metricsdebug/metricsdebug.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package metricsdebug 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "strings" 10 "text/tabwriter" 11 "time" 12 13 "github.com/juju/cmd" 14 "github.com/juju/errors" 15 "github.com/juju/names" 16 "launchpad.net/gnuflag" 17 18 "github.com/juju/juju/api/metricsdebug" 19 "github.com/juju/juju/apiserver/params" 20 "github.com/juju/juju/cmd/modelcmd" 21 ) 22 23 const debugMetricsDoc = ` 24 debug-metrics 25 display recently collected metrics and exit 26 ` 27 28 // DebugMetricsCommand retrieves metrics stored in the juju controller. 29 type DebugMetricsCommand struct { 30 modelcmd.ModelCommandBase 31 Json bool 32 Tag names.Tag 33 Count int 34 } 35 36 // New creates a new DebugMetricsCommand. 37 func New() cmd.Command { 38 return modelcmd.Wrap(&DebugMetricsCommand{}) 39 } 40 41 // Info implements Command.Info. 42 func (c *DebugMetricsCommand) Info() *cmd.Info { 43 return &cmd.Info{ 44 Name: "debug-metrics", 45 Args: "[service or unit]", 46 Purpose: "retrieve metrics collected by the given unit/service", 47 Doc: debugMetricsDoc, 48 } 49 } 50 51 // Init reads and verifies the cli arguments for the DebugMetricsCommand 52 func (c *DebugMetricsCommand) Init(args []string) error { 53 if len(args) == 0 { 54 return errors.New("you need to specify a unit or service.") 55 } 56 if names.IsValidUnit(args[0]) { 57 c.Tag = names.NewUnitTag(args[0]) 58 } else if names.IsValidService(args[0]) { 59 c.Tag = names.NewServiceTag(args[0]) 60 } else { 61 return errors.Errorf("%q is not a valid unit or service", args[0]) 62 } 63 if err := cmd.CheckEmpty(args[1:]); err != nil { 64 return errors.Errorf("unknown command line arguments: " + strings.Join(args, ",")) 65 } 66 return nil 67 } 68 69 // SetFlags implements Command.SetFlags. 70 func (c *DebugMetricsCommand) SetFlags(f *gnuflag.FlagSet) { 71 c.ModelCommandBase.SetFlags(f) 72 f.IntVar(&c.Count, "n", 0, "number of metrics to retrieve") 73 f.BoolVar(&c.Json, "json", false, "output metrics as json") 74 } 75 76 type GetMetricsClient interface { 77 GetMetrics(tag string) ([]params.MetricResult, error) 78 Close() error 79 } 80 81 var newClient = func(env modelcmd.ModelCommandBase) (GetMetricsClient, error) { 82 state, err := env.NewAPIRoot() 83 if err != nil { 84 return nil, errors.Trace(err) 85 } 86 return metricsdebug.NewClient(state), nil 87 } 88 89 // Run implements Command.Run. 90 func (c *DebugMetricsCommand) Run(ctx *cmd.Context) error { 91 client, err := newClient(c.ModelCommandBase) 92 if err != nil { 93 return errors.Trace(err) 94 } 95 metrics, err := client.GetMetrics(c.Tag.String()) 96 if err != nil { 97 return errors.Trace(err) 98 } 99 defer client.Close() 100 if len(metrics) == 0 { 101 return nil 102 } 103 if c.Count > 0 && len(metrics) > c.Count { 104 metrics = metrics[:c.Count] 105 } 106 if c.Json { 107 b, err := json.MarshalIndent(metrics, "", " ") 108 if err != nil { 109 return errors.Trace(err) 110 } 111 fmt.Fprintf(ctx.Stdout, string(b)) 112 return nil 113 } 114 tw := tabwriter.NewWriter(ctx.Stdout, 0, 1, 1, ' ', 0) 115 fmt.Fprintf(tw, "TIME\tMETRIC\tVALUE\n") 116 for _, m := range metrics { 117 fmt.Fprintf(tw, "%v\t%v\t%v\n", m.Time.Format(time.RFC3339), m.Key, m.Value) 118 } 119 tw.Flush() 120 return nil 121 }