Beispiel #1
0
func (r *Reporter) Init(c *client.Config) {
	reporters := strings.Split(reporterDestinations, ":")
	for _, rep := range reporters {
		newRep, err := reporter.Get(rep)
		if err != nil {
			if sentryClient := sentry.GetClient(); sentryClient != nil {
				sentryClient.CaptureError(err, map[string]string{})
			}

			// Allow other reporters to proceed
			continue
		}

		if newRep != nil {
			log.Printf("[multireporter] Initialization successful: %s", rep)
			r.reporterDestinations = append(r.reporterDestinations, newRep)
		}
	}

	log.Printf("[multireporter] Setting up multiple client reporters: %s\n", reporters)

	for _, rep := range r.reporterDestinations {
		rep.Init(c)
	}
}
Beispiel #2
0
// Utility method for sending a payload. This wraps httpPost in a framework
// nicer for the Reporter itself, as it turns the ReportPayload into its
// associated params (which corresponds to its data). We also attempt
// httpPost multiple times in order to account for flakiness in the
// network connection. This function is synchronous.
func sendPayload(r *Reporter, rp ReportPayload) {
	var (
		resp   *http.Response
		err    error
		status string
	)

	path := r.publishUri + rp.path
	if rp.data == nil {
		rp.data = make(map[string]string)
	}

	rp.data["date"] = time.Now().UTC().Format("2006-01-02T15:04:05.0Z")
	for tryCnt := 1; tryCnt <= numPublishRetries; tryCnt++ {
		log.Printf("[reporter] POST %s try: %d", path, tryCnt)
		resp, err = httpPost(path, rp.data, rp.filename)

		if resp != nil {
			status = resp.Status
		} else {
			status = "-1"
		}

		if resp != nil && resp.StatusCode/100 == 2 {
			break
		}

		var errmsg string
		if err != nil {
			errmsg = err.Error()
		} else {
			// If there wasn't an IO error, use the response body as the error message.
			var bodyData bytes.Buffer
			if _, e := bodyData.ReadFrom(resp.Body); e != nil {
				log.Printf("[reporter] Error reading POST %s response body: %s", path, e)
			}
			errmsg = bodyData.String()
		}
		log.Printf("[reporter] POST %s failed, try: %d, resp: %s, err: %s",
			path, tryCnt, status, errmsg)

		/* We are unable to publish to the endpoint.
		 * Fail fast and let the above layers handle the outage */
		if tryCnt == numPublishRetries {
			const msg = "Couldn't to connect to publish endpoint"
			if client := sentry.GetClient(); client != nil {
				client.CaptureMessageAndWait(msg, nil)
			}
			// TODO: Report an infra failure rather than panicing.
			panic(msg)
		}
		log.Printf("[reporter] Sleep for %d ms", backoffTimeMs)
		time.Sleep(time.Duration(backoffTimeMs) * time.Millisecond)
	}
}
Beispiel #3
0
// Returns whether run was successful.
func run() bool {
	var sentryClient *raven.Client
	if sentryClient = sentry.GetClient(); sentryClient != nil {
		log.Printf("Using Sentry; ProjectID=%s, URL=%s", sentryClient.ProjectID(), sentryClient.URL())
		// Don't return until we're finished sending to Sentry.
		defer sentryClient.Wait()
		// Ensure main thread panics are caught and reported.
		defer func() {
			if p := recover(); p != nil {
				var err error
				switch rval := p.(type) {
				case error:
					err = rval
				default:
					err = errors.New(fmt.Sprint(rval))
				}
				packet := raven.NewPacket(err.Error(), raven.NewException(err, raven.NewStacktrace(2, 3, nil)))
				log.Printf("[client] Sending panic to Sentry")
				_, ch := sentryClient.Capture(packet, map[string]string{})
				if serr := <-ch; serr != nil {
					log.Printf("SENTRY ERROR: %s", serr)
				}
				panic(p)
			}
		}()
	} else {
		log.Println("Sentry NOT ENABLED.")
	}

	// Error handling in place; now we begin.

	config, err := client.GetConfig()
	if err != nil {
		panic(err)
	}
	if sentryClient != nil {
		sentryClient.SetTagsContext(map[string]string{
			"projectslug": config.Project.Slug,
			"jobstep_id":  config.JobstepID,
		})
	}

	result, err := engine.RunBuildPlan(config)
	log.Printf("[client] Finished: %s", result)
	if err != nil {
		log.Printf("[client] error: %s", err)
		sentry.Error(err, map[string]string{})
	}
	return err == nil && result == engine.RESULT_PASSED
}
Beispiel #4
0
// Returns whether run was successful.
func run() bool {
	if sentryClient := sentry.GetClient(); sentryClient != nil {
		// Don't return until we're finished sending to Sentry.
		defer sentryClient.Wait()
		// Ensure main thread panics are caught and reported.
		defer func() {
			if p := recover(); p != nil {
				var err error
				switch rval := p.(type) {
				case error:
					err = rval
				default:
					err = errors.New(fmt.Sprint(rval))
				}
				packet := raven.NewPacket(err.Error(), raven.NewException(err, raven.NewStacktrace(2, 3, nil)))
				log.Printf("[client] Sending panic to Sentry")
				_, ch := sentryClient.Capture(packet, map[string]string{})
				<-ch
				panic(p)
			}
		}()
	}

	// Error handling in place; now we begin.

	config, err := client.GetConfig()
	if err != nil {
		panic(err)
	}

	result, err := engine.RunBuildPlan(config)
	log.Printf("[client] Finished: %s", result)
	if err != nil {
		log.Printf("[client] error: %s", err)
		sentry.Error(err, nil)
	}
	return err == nil && result == engine.RESULT_PASSED
}