// QOSEventSend sends an internal CLI event to segment for quality-of-service purposes. // If the event is an error it also sends the error to rollbar, then displays the // error to the user and exits non-zero. func QOSEventSend(system, id string, ep QOSEventProperties) error { rollbar.Token = "8481f1ec73f549ce8b81711ca4fdf98a" rollbar.Environment = id segment := analytics.New("JcNCirASuqEvuWhL8K87JTsUkhY68jvX") props := map[string]interface{}{} if ep.Error != nil { props["error"] = ep.Error.Error() rollbar.Error(rollbar.ERR, ep.Error, &rollbar.Field{"id", id}) } if ep.ValidationError != nil { props["validation_error"] = ep.ValidationError.Error() } if ep.AppType != "" { props["app_type"] = ep.AppType } if !ep.Start.IsZero() { props["elapsed"] = float64(time.Since(ep.Start).Nanoseconds()) / 1000000 } err := segment.Track(&analytics.Track{ Event: system, UserId: id, Properties: props, }) if err != nil { rollbar.Error(rollbar.ERR, err, &rollbar.Field{"id", id}) } err = segment.Close() if err != nil { rollbar.Error(rollbar.ERR, err, &rollbar.Field{"id", id}) } if os.Getenv("ROLLBAR_TOKEN") != "" { rollbar.Wait() } if ep.ValidationError != nil { return ExitError(ep.ValidationError) } if ep.Error != nil { return ExitError(ep.Error) } return nil }
func api(at string, handler ApiHandlerFunc) http.HandlerFunc { return func(rw http.ResponseWriter, r *http.Request) { log := logger.New("ns=kernel").At(at).Start() if !passwordCheck(r) { rw.Header().Set("WWW-Authenticate", `Basic realm="Convox System"`) rw.WriteHeader(401) rw.Write([]byte("invalid authorization")) return } if !versionCheck(r) { rw.WriteHeader(403) rw.Write([]byte("client outdated, please update with `convox update`")) return } err := handler(rw, r) if err != nil { log.Error(err) rollbar.Error(rollbar.ERR, err) RenderError(rw, err) return } log.Log("state=success") } }
func ws(at string, handler ApiWebsocketFunc) websocket.Handler { return websocket.Handler(func(ws *websocket.Conn) { log := logger.New("ns=kernel").At(at).Start() if !passwordCheck(ws.Request()) { ws.Write([]byte("ERROR: invalid authorization\n")) return } if !versionCheck(ws.Request()) { ws.Write([]byte("client outdated, please update with `convox update`\n")) return } err := handler(ws) if err != nil { ws.Write([]byte(fmt.Sprintf("ERROR: %v\n", err))) log.Error(err) rollbar.Error(rollbar.ERR, err) return } log.Log("state=success") }) }
func (p *program) run() error { // Allow the main thread to finish // This prevents the service from being terminated runtime.Gosched() p.init() ticker := time.Tick(3 * time.Hour) for { logger.Info("Fetching new results") if err := p.client.Run(); err != nil { logger.Error(err) rollbar.Error(rollbar.ERR, err) } if p.client.Changed() { logger.Info("New results detected. Sending email...") p.SendMail() } logger.Info("Going back to sleep") // Sleep until the next update time select { case <-ticker: } } return nil }
func main() { app := cli.NewApp() app.Name = "Scalingo Client" app.Author = "Scalingo Team" app.Email = "*****@*****.**" app.Usage = "Manage your apps and containers" app.Version = config.Version app.CategorizedHelp = true app.Flags = []cli.Flag{ cli.StringFlag{Name: "app, a", Value: "<name>", Usage: "Name of the app", EnvVar: "SCALINGO_APP"}, cli.StringFlag{Name: "remote, r", Value: "scalingo", Usage: "Name of the remote", EnvVar: ""}, } app.EnableBashCompletion = true app.BashComplete = func(c *cli.Context) { ScalingoAppComplete(c) } app.Action = DefaultAction // Commands for _, command := range cmd.Commands { oldFunc := command.BashComplete command.BashComplete = func(c *cli.Context) { n := len(os.Args) - 2 if n > 0 && !autocomplete.FlagsAutoComplete(c, os.Args[n]) && oldFunc != nil { oldFunc(c) } } app.Commands = append(app.Commands, command) } go signals.Handle() bashComplete := false for i := range os.Args { if strings.Contains(os.Args[i], "generate-bash-completion") { bashComplete = true } } if !bashComplete { if len(os.Args) >= 2 && os.Args[1] == cmd.UpdateCommand.Name { err := update.Check() if err != nil { rollbar.Error(rollbar.ERR, err) } return } else { defer update.Check() } } else { // If we are completing stuff, disable logging config.C.DisableInteractive = true } if err := app.Run(os.Args); err != nil { fmt.Println("Fail to run scalingo", err) } }
func handlePanic() { if rec := recover(); rec != nil { err, ok := rec.(error) if !ok { err = errors.New(rec.(string)) } Errln("ERROR:", err) if Channel == "?" { debug.PrintStack() } else { rollbar.Error(rollbar.ERR, err, rollbarFields()...) rollbar.Wait() } Exit(1) } }
func Error(log *logger.Logger, err error) { if log != nil { log.Error(err) } if rollbar.Token != "" { extraData := map[string]string{ "AWS_REGION": os.Getenv("AWS_REGION"), "RACK": os.Getenv("RACK"), "RELEASE": os.Getenv("RELEASE"), "VPC": os.Getenv("VPC"), } extraField := &rollbar.Field{"env", extraData} rollbar.Error(rollbar.ERR, err, extraField) } }
func ReportCriticalVerbose(err error, message string, fields map[string]string) { fields["message"] = message rollbarFields := mapToRollbarFields(fields) rollbar.Error("critical", err, rollbarFields...) }
func (p *program) SendMail() { win := p.client.CheckWin(config.Config.Target) templateVars := map[string]string{} message := &mandrill.Message{} if win { message.Subject = "WIN --- Postcode Lottery" } else { message.Subject = "Postcode Lottery" } message.InlineCSS = true message.Subaccount = "fpl" message.FromEmail = config.Config.Services.Mandrill.Sender.Email message.FromName = config.Config.Services.Mandrill.Sender.Name message.AddRecipient(config.Config.Target, config.Config.Target, "to") if p.daily.Changed() { att := &mandrill.Attachment{ Type: "image/png", Name: "daily", Content: p.daily.GetEncodedImage(), } templateVars["daily"] = "CHANGED" message.Attachments = make([]*mandrill.Attachment, 1) message.Attachments[0] = att } // Global vars if p.stockpot.Changed() { templateVars["stockpot"] = strings.Join(p.stockpot.GetPostcodes(), "<br>") } if p.survey.Changed() { templateVars["survey"] = p.survey.GetPostcode() } message.GlobalMergeVars = mandrill.MapToVars(templateVars) templateContent := map[string]string{} responses, err := p.mailer.MessagesSendTemplate(message, "fpl", templateContent) if err != nil { rollbar.Error(rollbar.ERR, err) if config.Config.Debug { logger.Error(err) } } for _, response := range responses { if strings.EqualFold(response.Status, "rejected") || strings.EqualFold(response.Status, "invalid") { apiErrorField := &rollbar.Field{Name: "Response", Data: response} rollbar.Error(rollbar.ERR, fmt.Errorf("Email send failed"), apiErrorField) if config.Config.Debug { logger.Error(response) } } } }