123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package system
- import (
- "fmt"
- "io"
- "sort"
- "strings"
- "time"
- "golang.org/x/net/context"
- "github.com/docker/docker/api/client"
- "github.com/docker/docker/cli"
- "github.com/docker/docker/pkg/jsonlog"
- "github.com/docker/engine-api/types"
- eventtypes "github.com/docker/engine-api/types/events"
- "github.com/docker/engine-api/types/filters"
- "github.com/spf13/cobra"
- )
- type eventsOptions struct {
- since string
- until string
- filter []string
- }
- // NewEventsCommand creates a new cobra.Command for `docker events`
- func NewEventsCommand(dockerCli *client.DockerCli) *cobra.Command {
- var opts eventsOptions
- cmd := &cobra.Command{
- Use: "events [OPTIONS]",
- Short: "Get real time events from the server",
- Args: cli.NoArgs,
- RunE: func(cmd *cobra.Command, args []string) error {
- return runEvents(dockerCli, &opts)
- },
- }
- flags := cmd.Flags()
- flags.StringVar(&opts.since, "since", "", "Show all events created since timestamp")
- flags.StringVar(&opts.until, "until", "", "Stream events until this timestamp")
- flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided")
- return cmd
- }
- func runEvents(dockerCli *client.DockerCli, opts *eventsOptions) error {
- eventFilterArgs := filters.NewArgs()
- // Consolidate all filter flags, and sanity check them early.
- // They'll get process in the daemon/server.
- for _, f := range opts.filter {
- var err error
- eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs)
- if err != nil {
- return err
- }
- }
- options := types.EventsOptions{
- Since: opts.since,
- Until: opts.until,
- Filters: eventFilterArgs,
- }
- responseBody, err := dockerCli.Client().Events(context.Background(), options)
- if err != nil {
- return err
- }
- defer responseBody.Close()
- return streamEvents(responseBody, dockerCli.Out())
- }
- // streamEvents decodes prints the incoming events in the provided output.
- func streamEvents(input io.Reader, output io.Writer) error {
- return DecodeEvents(input, func(event eventtypes.Message, err error) error {
- if err != nil {
- return err
- }
- printOutput(event, output)
- return nil
- })
- }
- type eventProcessor func(event eventtypes.Message, err error) error
- // printOutput prints all types of event information.
- // Each output includes the event type, actor id, name and action.
- // Actor attributes are printed at the end if the actor has any.
- func printOutput(event eventtypes.Message, output io.Writer) {
- if event.TimeNano != 0 {
- fmt.Fprintf(output, "%s ", time.Unix(0, event.TimeNano).Format(jsonlog.RFC3339NanoFixed))
- } else if event.Time != 0 {
- fmt.Fprintf(output, "%s ", time.Unix(event.Time, 0).Format(jsonlog.RFC3339NanoFixed))
- }
- fmt.Fprintf(output, "%s %s %s", event.Type, event.Action, event.Actor.ID)
- if len(event.Actor.Attributes) > 0 {
- var attrs []string
- var keys []string
- for k := range event.Actor.Attributes {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, k := range keys {
- v := event.Actor.Attributes[k]
- attrs = append(attrs, fmt.Sprintf("%s=%s", k, v))
- }
- fmt.Fprintf(output, " (%s)", strings.Join(attrs, ", "))
- }
- fmt.Fprint(output, "\n")
- }
|