// sendLogEntries sends a logEntry bundle to the Cloud Logging system. func (l *cloudLogging) sendLogEntries(entries []*logEntry, index int64) error { if len(entries) == 0 { return nil } logEntries := make([]*cloudlog.LogEntry, len(entries)) for idx, e := range entries { logEntries[idx] = l.buildLogEntry(e, index, int64(idx)) } req := cloudlog.WriteLogEntriesRequest{ CommonLabels: l.labels, Entries: logEntries, } svc := cloudlog.NewProjectsLogsEntriesService(l.service) call := svc.Write(l.projectName, l.logsID, &req) return retry.Retry(l.ctx, func() error { _, err := call.Do() return err }, func(err error, delay time.Duration) { // Write error to STDERR. fmt.Fprintf(os.Stderr, "WARNING: Failed to send log entries {err=%s, delay=%s, entries=%s}\n", err, delay, entries) }) }
// publishLogs writes a slice of log Entry to the wrapped Client. The underlying // PushEntries call will be retried. func (b *bufferImpl) publishLogs(entries []*Entry) { // If we are aborted, Retry will detect this and abort. err := retry.Retry(b.ctx, b.newRetryIterator(), func() error { return b.client.PushEntries(entries) }, func(err error, delay time.Duration) { b.writeError("cloudlogging: Failed to push entries, retrying in %v: %v", delay, err) }) if err != nil { b.writeError("cloudlogging: Failed to push entries: %s", err) } }
// retryCall is a wrapper around the retry library that logs information about // the retry attempts. func retryCall(ctx context.Context, title string, f func() error) error { log.Debugf(ctx, "Executing retriable call %s.", title) err := retry.Retry(ctx, func() error { return f() }, func(err error, delay time.Duration) { log.Fields{ log.ErrorKey: err, "delay": delay, }.Warningf(ctx, "Transient error encountered during %s; retrying.", title) }) if err != nil { log.Errorf(log.SetError(ctx, err), "Failed to %s.", title) return err } return nil }