github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/cli/export.go (about) 1 package cli 2 3 import ( 4 "io" 5 "os" 6 7 "github.com/pkg/errors" 8 ) 9 10 var ( 11 GranularityDays = "day" 12 GranularityMinutes = "minute" 13 GranularitySeconds = "second" 14 GranularityHours = "hour" 15 16 HostUtilizationStat = "host" 17 AverageScheduledToStart = "avg" 18 OptimalMakespanStat = "makespan" 19 ) 20 21 // ExportCommand is used to export statistics 22 type ExportCommand struct { 23 GlobalOpts *Options `no-flag:"true"` 24 JSON bool `long:"json" description:"set the format to export to json"` 25 Granularity string `long:"granularity" description:"set the granularity, default hour, options are 'second', 'minute', 'hour'"` 26 Days int `long:"days" description:"set the number of days, default 1, max of 30 days back"` 27 StatsType string `long:"stat" description:"include the type of stats - 'host' for host utilization,'avg' for average scheduled to start times, 'makespan' for makespan ratios" required:"true"` 28 DistroId string `long:"distro" description:"distro id - required for average scheduled to start times"` 29 Number int `long:"number" description:"set the number of revisions (for getting build makespan), default 100"` 30 Filepath string `long:"filepath" description:"path to directory where csv file is to be saved"` 31 } 32 33 func (ec *ExportCommand) Execute(_ []string) error { 34 _, rc, _, err := getAPIClients(ec.GlobalOpts) 35 if err != nil { 36 return err 37 } 38 39 if ec.StatsType == "" { 40 return errors.New("Must specify a stats type, host") 41 } 42 43 // default granularity to an hour 44 if ec.Granularity == "" { 45 ec.Granularity = GranularityHours 46 } 47 48 // default days to 1 49 if ec.Days == 0 { 50 ec.Days = 1 51 } 52 53 if ec.Number == 0 { 54 ec.Number = 100 55 } 56 57 isCSV := !ec.JSON 58 59 var body io.ReadCloser 60 var granSeconds int 61 62 switch ec.StatsType { 63 case HostUtilizationStat: 64 granSeconds, err = convertGranularityToSeconds(ec.Granularity) 65 if err != nil { 66 return err 67 } 68 body, err = rc.GetHostUtilizationStats(granSeconds, ec.Days, isCSV) 69 if err != nil { 70 return err 71 } 72 case AverageScheduledToStart: 73 if ec.DistroId == "" { 74 return errors.New("cannot have empty distro id") 75 } 76 granSeconds, err = convertGranularityToSeconds(ec.Granularity) 77 if err != nil { 78 return err 79 } 80 body, err = rc.GetAverageSchedulerStats(granSeconds, ec.Days, ec.DistroId, isCSV) 81 if err != nil { 82 return err 83 } 84 case OptimalMakespanStat: 85 body, err = rc.GetOptimalMakespans(ec.Number, isCSV) 86 if err != nil { 87 return err 88 } 89 90 default: 91 return errors.Errorf("%v is not a valid stats type. The current valid types include, host, avg, and makespan", ec.StatsType) 92 93 } 94 95 return WriteToFile(body, ec.Filepath) 96 } 97 98 // convertGranularityToSeconds takes in a string granularity and returns its 99 func convertGranularityToSeconds(granString string) (int, error) { 100 switch granString { 101 case GranularityDays: 102 return 24 * 60 * 60, nil 103 case GranularityHours: 104 return 60 * 60, nil 105 case GranularityMinutes: 106 return 60, nil 107 case GranularitySeconds: 108 return 1, nil 109 default: 110 return 0, errors.Errorf("not a valid granularity, %v", granString) 111 } 112 } 113 114 // WriteToFile takes in a body and filepath and writes out the data in the body 115 func WriteToFile(body io.ReadCloser, filepath string) error { 116 defer body.Close() 117 file := os.Stdout 118 var err error 119 if filepath != "" { 120 file, err = os.Create(filepath) 121 if err != nil { 122 return err 123 } 124 defer file.Close() 125 } 126 _, err = io.Copy(file, body) 127 return err 128 129 }