github.com/vmware/govmomi@v0.51.0/cli/metric/ls.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package metric 6 7 import ( 8 "context" 9 "encoding/json" 10 "flag" 11 "fmt" 12 "io" 13 "text/tabwriter" 14 15 "github.com/vmware/govmomi/cli" 16 "github.com/vmware/govmomi/performance" 17 "github.com/vmware/govmomi/vim25/types" 18 ) 19 20 type ls struct { 21 *PerformanceFlag 22 23 group string 24 long bool 25 longlong bool 26 } 27 28 func init() { 29 cli.Register("metric.ls", &ls{}) 30 } 31 32 func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { 33 cmd.PerformanceFlag, ctx = NewPerformanceFlag(ctx) 34 cmd.PerformanceFlag.Register(ctx, f) 35 36 f.StringVar(&cmd.group, "g", "", "List a specific Group") 37 f.BoolVar(&cmd.long, "l", false, "Long listing format") 38 f.BoolVar(&cmd.longlong, "L", false, "Longer listing format") 39 } 40 41 func (cmd *ls) Usage() string { 42 return "PATH" 43 } 44 45 func (cmd *ls) Description() string { 46 return `List available metrics for PATH. 47 48 The default output format is the metric name. 49 The '-l' flag includes the metric description. 50 The '-L' flag includes the metric units, instance count (if any) and description. 51 The instance count is prefixed with a single '@'. 52 If no aggregate is provided for the metric, instance count is prefixed with two '@@'. 53 54 Examples: 55 govc metric.ls /dc1/host/cluster1 56 govc metric.ls datastore/* 57 govc metric.ls -L -g CPU /dc1/host/cluster1/host1 58 govc metric.ls vm/* | grep mem. | xargs govc metric.sample vm/*` 59 } 60 61 func (cmd *ls) Process(ctx context.Context) error { 62 if err := cmd.PerformanceFlag.Process(ctx); err != nil { 63 return err 64 } 65 return nil 66 } 67 68 type lsResult struct { 69 cmd *ls 70 counters map[int32]*types.PerfCounterInfo 71 performance.MetricList 72 } 73 74 func (r *lsResult) Write(w io.Writer) error { 75 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 76 77 type count struct { 78 aggregate bool 79 instances int 80 } 81 seen := make(map[int32]*count) 82 var res []types.PerfMetricId 83 84 for _, id := range r.MetricList { 85 if r.cmd.group != "" { 86 info, ok := r.counters[id.CounterId] 87 if !ok || info.GroupInfo.GetElementDescription().Label != r.cmd.group { 88 continue 89 } 90 } 91 92 c := seen[id.CounterId] 93 if c == nil { 94 c = new(count) 95 seen[id.CounterId] = c 96 res = append(res, id) 97 } 98 99 if id.Instance == "" { 100 c.aggregate = true 101 } else { 102 c.instances++ 103 } 104 } 105 106 for _, id := range res { 107 info, ok := r.counters[id.CounterId] 108 if !ok { 109 continue 110 } 111 112 switch { 113 case r.cmd.long: 114 fmt.Fprintf(tw, "%s\t%s\n", info.Name(), 115 info.NameInfo.GetElementDescription().Label) 116 case r.cmd.longlong: 117 i := "" 118 c := seen[id.CounterId] 119 if !c.aggregate { 120 i = "@" 121 } 122 if c.instances > 0 { 123 i += fmt.Sprintf("@%d", c.instances) 124 } 125 fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", info.Name(), 126 i, 127 info.UnitInfo.GetElementDescription().Label, 128 info.NameInfo.GetElementDescription().Label) 129 default: 130 fmt.Fprintln(w, info.Name()) 131 } 132 } 133 134 return tw.Flush() 135 } 136 137 func (r *lsResult) MarshalJSON() ([]byte, error) { 138 m := make(map[string]*types.PerfCounterInfo) 139 140 for _, id := range r.MetricList { 141 if info, ok := r.counters[id.CounterId]; ok { 142 m[info.Name()] = info 143 } 144 } 145 146 return json.Marshal(m) 147 } 148 149 func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { 150 if f.NArg() != 1 { 151 return flag.ErrHelp 152 } 153 154 objs, err := cmd.ManagedObjects(ctx, f.Args()) 155 if err != nil { 156 return err 157 } 158 159 m, err := cmd.Manager(ctx) 160 if err != nil { 161 return err 162 } 163 164 s, err := m.ProviderSummary(ctx, objs[0]) 165 if err != nil { 166 return err 167 } 168 169 mids, err := m.AvailableMetric(ctx, objs[0], cmd.Interval(s.RefreshRate)) 170 if err != nil { 171 return err 172 } 173 174 counters, err := m.CounterInfoByKey(ctx) 175 if err != nil { 176 return err 177 } 178 179 return cmd.WriteResult(&lsResult{cmd, counters, mids}) 180 }