in event-exporter/sinks/stackdriver/writer.go [49:90]
func (w sdWriterImpl) Write(entries []*sd.LogEntry, logName string, resource *sd.MonitoredResource) {
req := &sd.WriteLogEntriesRequest{
Entries: entries,
LogName: logName,
Resource: resource,
}
// We retry forever, until request either succeeds or API returns
// BadRequest, which means that the request is malformed, e.g. because
// it contains too large entries. This behavior mirrors the way logging
// agent pushes logs to Stackdriver.
for {
res, err := w.service.Entries.Write(req).Do()
// The entry is successfully sent to Stackdriver.
if err == nil {
requestCount.WithLabelValues(strconv.Itoa(res.HTTPStatusCode)).Inc()
successfullySentEntryCount.Add(float64(len(entries)))
measureLatencyOnSuccess(entries)
break
}
apiErr, ok := err.(*googleapi.Error)
if ok {
requestCount.WithLabelValues(strconv.Itoa(apiErr.Code)).Inc()
// Bad request from Stackdriver most probably indicates that some entries
// are in bad format, which means they won't be ingested after retry also,
// so it doesn't make sense to try again.
// TODO: Check response properly and return the actual number of
// successfully ingested entries, parsed out from the response body.
if apiErr.Code == http.StatusBadRequest {
glog.Warningf("Received bad request response from server, "+
"assuming some entries were rejected: %v", err)
break
}
}
glog.Warningf("Failed to send request to Stackdriver: %v", err)
time.Sleep(retryDelay)
}
}