func doCreate(c *cli.Context) { conffile := c.GlobalString("conf") argHostName := c.Args().Get(0) optRoleFullnames := c.StringSlice("roleFullname") optStatus := c.String("status") if argHostName == "" { cli.ShowCommandHelp(c, "create") os.Exit(1) } client := newMackerel(conffile) hostID, err := client.CreateHost(&mkr.CreateHostParam{ Name: argHostName, RoleFullnames: optRoleFullnames, }) logger.DieIf(err) logger.Log("created", hostID) if optStatus != "" { err := client.UpdateHostStatus(hostID, optStatus) logger.DieIf(err) logger.Log("updated", fmt.Sprintf("%s %s", hostID, optStatus)) } }
func doRetire(c *cli.Context) error { conffile := c.GlobalString("conf") force := c.Bool("force") argHostIDs := c.Args() if len(argHostIDs) < 1 { argHostIDs = make([]string, 1) if argHostIDs[0] = LoadHostIDFromConfig(conffile); argHostIDs[0] == "" { cli.ShowCommandHelp(c, "retire") os.Exit(1) } } if !force && !prompter.YN("Retire following hosts.\n "+strings.Join(argHostIDs, "\n ")+"\nAre you sure?", true) { logger.Log("", "retirement is canceled.") return nil } client := newMackerel(conffile) for _, hostID := range argHostIDs { err := client.RetireHost(hostID) logger.DieIf(err) logger.Log("retired", hostID) } return nil }
func doThrow(c *cli.Context) error { conffile := c.GlobalString("conf") optHostID := c.String("host") optService := c.String("service") var metricValues []*(mkr.MetricValue) scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() // name, value, timestamp // ex.) tcp.CLOSING 0 1397031808 items := strings.Fields(line) if len(items) != 3 { continue } value, err := strconv.ParseFloat(items[1], 64) if err != nil { logger.Log("warning", fmt.Sprintf("Failed to parse values: %s", err)) continue } time, err := strconv.ParseInt(items[2], 10, 64) if err != nil { logger.Log("warning", fmt.Sprintf("Failed to parse values: %s", err)) continue } metricValue := &mkr.MetricValue{ Name: items[0], Value: value, Time: time, } metricValues = append(metricValues, metricValue) } logger.ErrorIf(scanner.Err()) client := newMackerel(conffile) if optHostID != "" { err := client.PostHostMetricValuesByHostID(optHostID, metricValues) logger.DieIf(err) for _, metric := range metricValues { logger.Log("thrown", fmt.Sprintf("%s '%s\t%f\t%d'", optHostID, metric.Name, metric.Value, metric.Time)) } } else if optService != "" { err := client.PostServiceMetricValues(optService, metricValues) logger.DieIf(err) for _, metric := range metricValues { logger.Log("thrown", fmt.Sprintf("%s '%s\t%f\t%d'", optService, metric.Name, metric.Value, metric.Time)) } } else { cli.ShowCommandHelp(c, "throw") os.Exit(1) } return nil }
func doRetire(c *cli.Context) { conffile := c.GlobalString("conf") argHostIDs := c.Args() if len(argHostIDs) < 1 { argHostIDs = make([]string, 1) if argHostIDs[0] = LoadHostIDFromConfig(conffile); argHostIDs[0] == "" { cli.ShowCommandHelp(c, "retire") os.Exit(1) } } client := newMackerel(conffile) var wg sync.WaitGroup for _, hostID := range argHostIDs { wg.Add(1) go func(hostID string) { defer wg.Done() err := client.RetireHost(hostID) logger.DieIf(err) logger.Log("retired", hostID) }(hostID) } wg.Wait() }
func (s *AWSSession) crawlRDSMetrics(client *mkr.Client, rdss []*AWSElement) { for _, rds := range rdss { dimensions := []*cloudwatch.Dimension{ { Name: aws.String("DBInstanceIdentifier"), Value: aws.String(rds.Name), }} metricValues := s.getMetricStatistics(rds, rdsGraphdefs, "AWS/RDS", dimensions) logger.Log("info", fmt.Sprintf("%s", metricValues)) err := client.PostHostMetricValuesByHostID(rds.HostID, metricValues) //logger.DieIf(err) if err != nil { logger.Log("error", err.Error()) } for _, metric := range metricValues { logger.Log("thrown", fmt.Sprintf("%s '%s\t%f\t%d'", rds.HostID, metric.Name, metric.Value, metric.Time)) } } }
func (s *AWSSession) crawlELBMetrics(client *mkr.Client, elbs []*AWSElement) { for _, elb := range elbs { dimensions := []*cloudwatch.Dimension{ { Name: aws.String("LoadBalancerName"), Value: aws.String(elb.Name), }} metricValues := s.getMetricStatistics(elb, elbGraphdefs, "AWS/ELB", dimensions) logger.Log("info", fmt.Sprintf("%s", metricValues)) err := client.PostHostMetricValuesByHostID(elb.HostID, metricValues) //logger.DieIf(err) if err != nil { logger.Log("error", err.Error()) } for _, metric := range metricValues { logger.Log("thrown", fmt.Sprintf("%s '%s\t%f\t%d'", elb.HostID, metric.Name, metric.Value, metric.Time)) } } }
func doUpdate(c *cli.Context) { conffile := c.GlobalString("conf") argHostIDs := c.Args() optName := c.String("name") optStatus := c.String("status") optRoleFullnames := c.StringSlice("roleFullname") if len(argHostIDs) < 1 { argHostIDs = make([]string, 1) if argHostIDs[0] = LoadHostIDFromConfig(conffile); argHostIDs[0] == "" { cli.ShowCommandHelp(c, "update") os.Exit(1) } } needUpdateHostStatus := optStatus != "" needUpdateHost := (optName != "" || len(optRoleFullnames) > 0) if !needUpdateHostStatus && !needUpdateHost { cli.ShowCommandHelp(c, "update") os.Exit(1) } client := newMackerel(conffile) var wg sync.WaitGroup for _, hostID := range argHostIDs { wg.Add(1) go func(hostID string) { defer wg.Done() if needUpdateHostStatus { err := client.UpdateHostStatus(hostID, optStatus) logger.DieIf(err) } if needUpdateHost { _, err := client.UpdateHost(hostID, &mkr.UpdateHostParam{ Name: optName, RoleFullnames: optRoleFullnames, }) logger.DieIf(err) } logger.Log("updated", hostID) }(hostID) } wg.Wait() }
func (s *AWSSession) updateAWSElementList(elbs []*AWSElement, client *mkr.Client) { for _, elb := range elbs { hosts, err := client.FindHosts(&mkr.FindHostsParam{Name: elb.DNSName}) if err != nil { logger.Log("error", fmt.Sprintf("Mackerel FindHosts: %s", err.Error())) continue } if len(hosts) == 1 { elb.HostID = hosts[0].ID logger.Log("info", fmt.Sprintf("Host Found: %s -> %s", hosts[0].ID, hosts[0].Name)) } if len(hosts) == 0 { elb.HostID, err = client.CreateHost(&mkr.CreateHostParam{ Name: elb.DNSName, }) if err != nil { logger.Log("error", fmt.Sprintf("Mackerel CreateHost: %s", err.Error())) } } } return }
func doMonitorsPush(c *cli.Context) error { monitorDiff := checkMonitorsDiff(c) isDryRun := c.Bool("dry-run") isVerbose := c.Bool("verbose") conffile := c.GlobalString("conf") client := newMackerel(conffile) if isVerbose { client.Verbose = true } for _, m := range monitorDiff.onlyLocal { logger.Log("info", "Create a new rule.") fmt.Println(stringifyMonitor(m, "")) if !isDryRun { _, err := client.CreateMonitor(m) logger.DieIf(err) } } for _, m := range monitorDiff.onlyRemote { logger.Log("info", "Delete a rule.") fmt.Println(stringifyMonitor(m, "")) if !isDryRun { _, err := client.DeleteMonitor(m.ID) logger.DieIf(err) } } for _, d := range monitorDiff.diff { logger.Log("info", "Update a rule.") fmt.Println(stringifyMonitor(d.local, "")) if !isDryRun { _, err := client.UpdateMonitor(d.remote.ID, d.local) logger.DieIf(err) } } return nil }
func newMackerel(conffile string) *mkr.Client { apiKey := LoadApikeyFromEnvOrConfig(conffile) if apiKey == "" { logger.Log("error", ` Not set MACKEREL_APIKEY environment variable. (Try "export MACKEREL_APIKEY='<Your apikey>'") `) os.Exit(1) } if os.Getenv("DEBUG") != "" { mackerel, err := mkr.NewClientWithOptions(apiKey, "https://mackerel.io/api/v0", true) logger.DieIf(err) return mackerel } return mkr.NewClient(apiKey) }
func validateRules(monitors []*(mkr.Monitor), label string) (bool, error) { flagNameUniqueness := true // check each monitor for _, m := range monitors { v := reflect.ValueOf(m).Elem() for _, f := range []string{"Type"} { vf := v.FieldByName(f) if !vf.IsValid() || (vf.Type().String() == "string" && vf.Interface() == "") { return false, fmt.Errorf("Monitor '%s' should have '%s': %s", label, f, v.FieldByName(f).Interface()) } } switch m.Type { case "host", "service": for _, f := range []string{"Name", "Metric"} { vf := v.FieldByName(f) if !vf.IsValid() || (vf.Type().String() == "string" && vf.Interface() == "") { return false, fmt.Errorf("Monitor '%s' should have '%s': %s", label, f, v.FieldByName(f).Interface()) } } case "external": for _, f := range []string{"Name", "URL"} { vf := v.FieldByName(f) if !vf.IsValid() || (vf.Type().String() == "string" && vf.Interface() == "") { return false, fmt.Errorf("Monitor '%s' should have '%s': %s", label, f, v.FieldByName(f).Interface()) } } case "connectivity": default: return false, fmt.Errorf("Unknown type is found: %s", m.Type) } } // check name uniqueness names := map[string]bool{} for _, m := range monitors { if names[m.Name] { logger.Log("Warning: ", fmt.Sprintf("Names of %s are not unique.", label)) flagNameUniqueness = false } names[m.Name] = true } return flagNameUniqueness, nil }
func doMonitorsPull(c *cli.Context) error { conffile := c.GlobalString("conf") isVerbose := c.Bool("verbose") filePath := c.String("file-path") monitors, err := newMackerel(conffile).FindMonitors() logger.DieIf(err) monitorSaveRules(monitors, filePath) if isVerbose { PrettyPrintJSON(monitors) } if filePath == "" { filePath = "monitors.json" } logger.Log("info", fmt.Sprintf("Monitor rules are saved to '%s' (%d rules).", filePath, len(monitors))) return nil }
func doAlertsClose(c *cli.Context) error { conffile := c.GlobalString("conf") isVerbose := c.Bool("verbose") argAlertIDs := c.Args() reason := c.String("reason") if len(argAlertIDs) < 1 { cli.ShowCommandHelp(c, "alerts") os.Exit(1) } client := newMackerel(conffile) for _, alertID := range argAlertIDs { alert, err := client.CloseAlert(alertID, reason) logger.DieIf(err) logger.Log("Alert closed", alertID) if isVerbose == true { PrettyPrintJSON(alert) } } return nil }
func doUpdate(c *cli.Context) error { conffile := c.GlobalString("conf") argHostIDs := c.Args() optName := c.String("name") optDisplayName := c.String("displayName") optStatus := c.String("status") optRoleFullnames := c.StringSlice("roleFullname") overwriteRoles := c.Bool("overwriteRoles") if len(argHostIDs) < 1 { argHostIDs = make([]string, 1) if argHostIDs[0] = LoadHostIDFromConfig(conffile); argHostIDs[0] == "" { cli.ShowCommandHelp(c, "update") os.Exit(1) } } needUpdateHostStatus := optStatus != "" needUpdateRolesInHostUpdate := !overwriteRoles && len(optRoleFullnames) > 0 needUpdateHost := (optName != "" || optDisplayName != "" || overwriteRoles || needUpdateRolesInHostUpdate) if !needUpdateHostStatus && !needUpdateHost { logger.Log("update", "at least one argumet is required.") cli.ShowCommandHelp(c, "update") os.Exit(1) } client := newMackerel(conffile) for _, hostID := range argHostIDs { if needUpdateHostStatus { err := client.UpdateHostStatus(hostID, optStatus) logger.DieIf(err) } if overwriteRoles { err := client.UpdateHostRoleFullnames(hostID, optRoleFullnames) logger.DieIf(err) } if needUpdateHost { host, err := client.FindHost(hostID) logger.DieIf(err) meta := host.Meta name := "" if optName == "" { name = host.Name } else { name = optName } displayname := "" if optDisplayName == "" { displayname = host.DisplayName } else { displayname = optDisplayName } param := &mkr.UpdateHostParam{ Name: name, DisplayName: displayname, Meta: meta, } if needUpdateRolesInHostUpdate { param.RoleFullnames = optRoleFullnames } _, err = client.UpdateHost(hostID, param) logger.DieIf(err) } logger.Log("updated", hostID) } return nil }