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  }