github.com/ncdc/docker@v0.10.1-0.20160129113957-6c6729ef5b74/api/client/events.go (about) 1 package client 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "strings" 8 "time" 9 10 Cli "github.com/docker/docker/cli" 11 "github.com/docker/docker/opts" 12 "github.com/docker/docker/pkg/jsonlog" 13 flag "github.com/docker/docker/pkg/mflag" 14 "github.com/docker/engine-api/types" 15 eventtypes "github.com/docker/engine-api/types/events" 16 "github.com/docker/engine-api/types/filters" 17 ) 18 19 // CmdEvents prints a live stream of real time events from the server. 20 // 21 // Usage: docker events [OPTIONS] 22 func (cli *DockerCli) CmdEvents(args ...string) error { 23 cmd := Cli.Subcmd("events", nil, Cli.DockerCommands["events"].Description, true) 24 since := cmd.String([]string{"-since"}, "", "Show all events created since timestamp") 25 until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp") 26 flFilter := opts.NewListOpts(nil) 27 cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") 28 cmd.Require(flag.Exact, 0) 29 30 cmd.ParseFlags(args, true) 31 32 eventFilterArgs := filters.NewArgs() 33 34 // Consolidate all filter flags, and sanity check them early. 35 // They'll get process in the daemon/server. 36 for _, f := range flFilter.GetAll() { 37 var err error 38 eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs) 39 if err != nil { 40 return err 41 } 42 } 43 44 options := types.EventsOptions{ 45 Since: *since, 46 Until: *until, 47 Filters: eventFilterArgs, 48 } 49 50 responseBody, err := cli.client.Events(options) 51 if err != nil { 52 return err 53 } 54 defer responseBody.Close() 55 56 return streamEvents(responseBody, cli.out) 57 } 58 59 // streamEvents decodes prints the incoming events in the provided output. 60 func streamEvents(input io.Reader, output io.Writer) error { 61 return decodeEvents(input, func(event eventtypes.Message, err error) error { 62 if err != nil { 63 return err 64 } 65 printOutput(event, output) 66 return nil 67 }) 68 } 69 70 type eventProcessor func(event eventtypes.Message, err error) error 71 72 func decodeEvents(input io.Reader, ep eventProcessor) error { 73 dec := json.NewDecoder(input) 74 for { 75 var event eventtypes.Message 76 err := dec.Decode(&event) 77 if err != nil && err == io.EOF { 78 break 79 } 80 81 if procErr := ep(event, err); procErr != nil { 82 return procErr 83 } 84 } 85 return nil 86 } 87 88 // printOutput prints all types of event information. 89 // Each output includes the event type, actor id, name and action. 90 // Actor attributes are printed at the end if the actor has any. 91 func printOutput(event eventtypes.Message, output io.Writer) { 92 if event.TimeNano != 0 { 93 fmt.Fprintf(output, "%s ", time.Unix(0, event.TimeNano).Format(jsonlog.RFC3339NanoFixed)) 94 } else if event.Time != 0 { 95 fmt.Fprintf(output, "%s ", time.Unix(event.Time, 0).Format(jsonlog.RFC3339NanoFixed)) 96 } 97 98 fmt.Fprintf(output, "%s %s %s", event.Type, event.Action, event.Actor.ID) 99 100 if len(event.Actor.Attributes) > 0 { 101 var attrs []string 102 for k, v := range event.Actor.Attributes { 103 attrs = append(attrs, fmt.Sprintf("%s=%s", k, v)) 104 } 105 fmt.Fprintf(output, " (%s)", strings.Join(attrs, ", ")) 106 } 107 fmt.Fprint(output, "\n") 108 }