func (r *Reporter) Init(c *client.Config) { if artifactServer == "" { log.Printf("[artifactstorereporter] No artifact server url provided. Disabling reporter.") return } log.Printf("[artifactstorereporter] Setting up artifact store client: %s\n", artifactServer) r.client = artifacts.NewArtifactStoreClient(artifactServer) if len(artifactBucketId) == 0 { artifactBucketId = c.JobstepID } // TODO(anupc): At some point in the future, creating a new bucket should be driven by Changes // server, rather than being done by the test itself. It makes the process of integrating with // Changes common across both Mesos and Jenkins builds. // // TODO retry if bucket, err := r.client.NewBucket(artifactBucketId, "changes", 60); err != nil { sentry.Error(err, map[string]string{}) log.Printf("Error creating new bucket '%s' on artifact server: %s\n", artifactBucketId, err) return } else { log.Printf("Created new bucket %s\n", artifactBucketId) r.bucket = bucket } }
func (r *Reporter) Shutdown() { if r.bucket == nil { return } // Wait for queued uploads to complete. log.Printf("[artifactstore] Waiting for artifacts to upload...") for _, cArt := range r.chunkedArtifacts { if err := cArt.Flush(); err != nil { sentry.Error(err, map[string]string{}) } } log.Printf("[artifactstore] Artifacts finished uploading.") // Close the bucket. This implicitly closes all artifacts in the bucket. // TODO retry err := r.bucket.Close() if err != nil { sentry.Error(err, map[string]string{}) } }
// 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 }
// source: Name of the log stream. Usually, differentiates between stdout and stderr streams. // payload: Stream of bytes to append to this stream. func (r *Reporter) PushLogChunk(source string, payload []byte) { if r.bucket == nil { return } if _, ok := r.chunkedArtifacts[source]; !ok { if artifact, err := r.bucket.NewChunkedArtifact(source); err != nil { sentry.Error(err, map[string]string{}) log.Printf("Error creating console log artifact: %s\n", err) return } else { log.Printf("Created new artifact with name %s\n", source) r.chunkedArtifacts[source] = artifact } } logstream := r.chunkedArtifacts[source] logstream.AppendLog(string(payload[:])) }
func (r *Reporter) runWithDeadline(t time.Duration, f func()) { if r.isDisabled() { log.Println("Reporter is disabled. Not calling method") return } done := make(chan bool, 1) go func() { f() done <- true }() select { case <-time.After(t): sentry.Error(fmt.Errorf("Timed out after %s\n", t), map[string]string{}) r.markDeadlineExceeded() return case <-done: return } }
// 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 }