github.com/vmware/govmomi@v0.51.0/cli/events/command.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 events 6 7 import ( 8 "context" 9 "flag" 10 "fmt" 11 "io" 12 "os" 13 "reflect" 14 "strings" 15 "time" 16 17 "github.com/vmware/govmomi/cli" 18 "github.com/vmware/govmomi/cli/flags" 19 "github.com/vmware/govmomi/event" 20 "github.com/vmware/govmomi/vim25/types" 21 ) 22 23 type events struct { 24 *flags.DatacenterFlag 25 26 Max int32 27 Tail bool 28 Force bool 29 Long bool 30 Kind kinds 31 } 32 33 type kinds []string 34 35 func (e *kinds) String() string { 36 return fmt.Sprint(*e) 37 } 38 39 func (e *kinds) Set(value string) error { 40 *e = append(*e, value) 41 return nil 42 } 43 44 func init() { 45 // initialize with the maximum allowed objects set 46 cli.Register("events", &events{}) 47 } 48 49 func (cmd *events) Register(ctx context.Context, f *flag.FlagSet) { 50 cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) 51 cmd.DatacenterFlag.Register(ctx, f) 52 53 cmd.Max = 25 // default 54 f.Var(flags.NewInt32(&cmd.Max), "n", "Output the last N events") 55 f.BoolVar(&cmd.Tail, "f", false, "Follow event stream") 56 f.BoolVar(&cmd.Force, "force", false, "Disable number objects to monitor limit") 57 f.BoolVar(&cmd.Long, "l", false, "Long listing format") 58 f.Var(&cmd.Kind, "type", "Include only the specified event types") 59 } 60 61 func (cmd *events) Description() string { 62 return `Display events. 63 64 Examples: 65 govc events vm/my-vm1 vm/my-vm2 66 govc events /dc1/vm/* /dc2/vm/* 67 govc events -type VmPoweredOffEvent -type VmPoweredOnEvent 68 govc ls -t HostSystem host/* | xargs govc events | grep -i vsan` 69 } 70 71 func (cmd *events) Usage() string { 72 return "[PATH]..." 73 } 74 75 func (cmd *events) printEvents(ctx context.Context, obj *types.ManagedObjectReference, page []types.BaseEvent, m *event.Manager) error { 76 event.Sort(page) 77 source := "" 78 if obj != nil { 79 source = obj.String() 80 if !cmd.JSON { 81 // print the object reference 82 fmt.Fprintf(os.Stdout, "\n==> %s <==\n", source) 83 } 84 } 85 for _, e := range page { 86 cat, err := m.EventCategory(ctx, e) 87 if err != nil { 88 return err 89 } 90 91 event := e.GetEvent() 92 r := &record{ 93 Object: source, 94 CreatedTime: event.CreatedTime, 95 Category: cat, 96 Message: strings.TrimSpace(event.FullFormattedMessage), 97 event: e, 98 } 99 100 if cmd.Long { 101 r.Type = reflect.TypeOf(e).Elem().Name() 102 } 103 104 if cmd.Long { 105 r.Key = event.Key 106 } 107 108 switch x := e.(type) { 109 case *types.TaskEvent: 110 // some tasks won't have this information, so just use the event message 111 if x.Info.Entity != nil { 112 r.Message = fmt.Sprintf("%s (target=%s %s)", r.Message, x.Info.Entity.Type, x.Info.EntityName) 113 } 114 case *types.EventEx: 115 if r.Message == "" { 116 r.Message = x.Message 117 } 118 if x.ObjectId != "" { 119 r.Message = fmt.Sprintf("%s (%s)", r.Message, x.ObjectId) 120 } 121 if cmd.Long { 122 r.Type = x.EventTypeId 123 } 124 } 125 126 if err = cmd.WriteResult(r); err != nil { 127 return err 128 } 129 } 130 return nil 131 } 132 133 type record struct { 134 Object string `json:"object,omitempty"` 135 Type string `json:"type,omitempty"` 136 CreatedTime time.Time `json:"createdTime"` 137 Category string `json:"category"` 138 Message string `json:"message"` 139 Key int32 `json:"key,omitempty"` 140 141 event types.BaseEvent 142 } 143 144 // Dump the raw Event rather than the record struct. 145 func (r *record) Dump() any { 146 return r.event 147 } 148 149 func (r *record) Write(w io.Writer) error { 150 when := r.CreatedTime.Local().Format(time.ANSIC) 151 var kind, key string 152 if r.Type != "" { 153 kind = fmt.Sprintf(" [%s]", r.Type) 154 } 155 if r.Key != 0 { 156 key = fmt.Sprintf(" [%d]", r.Key) 157 } 158 _, err := fmt.Fprintf(w, "[%s] [%s]%s%s %s\n", when, r.Category, key, kind, r.Message) 159 return err 160 } 161 162 func (cmd *events) Run(ctx context.Context, f *flag.FlagSet) error { 163 c, err := cmd.Client() 164 if err != nil { 165 return err 166 } 167 168 objs, err := cmd.ManagedObjects(ctx, f.Args()) 169 if err != nil { 170 return err 171 } 172 173 m := event.NewManager(c) 174 175 return cmd.WithCancel(ctx, func(wctx context.Context) error { 176 return m.Events(wctx, objs, cmd.Max, cmd.Tail, cmd.Force, 177 func(obj types.ManagedObjectReference, ee []types.BaseEvent) error { 178 var o *types.ManagedObjectReference 179 if len(objs) > 1 { 180 o = &obj 181 } 182 183 return cmd.printEvents(ctx, o, ee, m) 184 }, cmd.Kind...) 185 }) 186 }