github.com/portworx/docker@v1.12.1/api/client/system/events.go (about) 1 package system 2 3 import ( 4 "fmt" 5 "io" 6 "sort" 7 "strings" 8 "time" 9 10 "golang.org/x/net/context" 11 12 "github.com/docker/docker/api/client" 13 "github.com/docker/docker/cli" 14 "github.com/docker/docker/pkg/jsonlog" 15 "github.com/docker/engine-api/types" 16 eventtypes "github.com/docker/engine-api/types/events" 17 "github.com/docker/engine-api/types/filters" 18 "github.com/spf13/cobra" 19 ) 20 21 type eventsOptions struct { 22 since string 23 until string 24 filter []string 25 } 26 27 // NewEventsCommand creats a new cobra.Command for `docker events` 28 func NewEventsCommand(dockerCli *client.DockerCli) *cobra.Command { 29 var opts eventsOptions 30 31 cmd := &cobra.Command{ 32 Use: "events [OPTIONS]", 33 Short: "Get real time events from the server", 34 Args: cli.NoArgs, 35 RunE: func(cmd *cobra.Command, args []string) error { 36 return runEvents(dockerCli, &opts) 37 }, 38 } 39 40 flags := cmd.Flags() 41 flags.StringVar(&opts.since, "since", "", "Show all events created since timestamp") 42 flags.StringVar(&opts.until, "until", "", "Stream events until this timestamp") 43 flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided") 44 45 return cmd 46 } 47 48 func runEvents(dockerCli *client.DockerCli, opts *eventsOptions) error { 49 eventFilterArgs := filters.NewArgs() 50 51 // Consolidate all filter flags, and sanity check them early. 52 // They'll get process in the daemon/server. 53 for _, f := range opts.filter { 54 var err error 55 eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs) 56 if err != nil { 57 return err 58 } 59 } 60 61 options := types.EventsOptions{ 62 Since: opts.since, 63 Until: opts.until, 64 Filters: eventFilterArgs, 65 } 66 67 responseBody, err := dockerCli.Client().Events(context.Background(), options) 68 if err != nil { 69 return err 70 } 71 defer responseBody.Close() 72 73 return streamEvents(responseBody, dockerCli.Out()) 74 } 75 76 // streamEvents decodes prints the incoming events in the provided output. 77 func streamEvents(input io.Reader, output io.Writer) error { 78 return DecodeEvents(input, func(event eventtypes.Message, err error) error { 79 if err != nil { 80 return err 81 } 82 printOutput(event, output) 83 return nil 84 }) 85 } 86 87 type eventProcessor func(event eventtypes.Message, err error) error 88 89 // printOutput prints all types of event information. 90 // Each output includes the event type, actor id, name and action. 91 // Actor attributes are printed at the end if the actor has any. 92 func printOutput(event eventtypes.Message, output io.Writer) { 93 if event.TimeNano != 0 { 94 fmt.Fprintf(output, "%s ", time.Unix(0, event.TimeNano).Format(jsonlog.RFC3339NanoFixed)) 95 } else if event.Time != 0 { 96 fmt.Fprintf(output, "%s ", time.Unix(event.Time, 0).Format(jsonlog.RFC3339NanoFixed)) 97 } 98 99 fmt.Fprintf(output, "%s %s %s", event.Type, event.Action, event.Actor.ID) 100 101 if len(event.Actor.Attributes) > 0 { 102 var attrs []string 103 var keys []string 104 for k := range event.Actor.Attributes { 105 keys = append(keys, k) 106 } 107 sort.Strings(keys) 108 for _, k := range keys { 109 v := event.Actor.Attributes[k] 110 attrs = append(attrs, fmt.Sprintf("%s=%s", k, v)) 111 } 112 fmt.Fprintf(output, " (%s)", strings.Join(attrs, ", ")) 113 } 114 fmt.Fprint(output, "\n") 115 }