1
0
Эх сурвалжийг харах

Improve logging for S3RetryingInputStream (#104892)

* Improve logging for S3RetryingInputStream

This PR adds a logging message when opening or read succeeds after
retries. See also
https://github.com/elastic/elasticsearch/pull/103300#issuecomment-1882130933

It also makes the logging messages for retries exponentially
less so that the log size is more scalable when there are many threads
retrying. See also
https://github.com/elastic/elasticsearch/pull/103300#discussion_r1452149913

Relates: #103300
Yang Wang 1 жил өмнө
parent
commit
5af58ed033

+ 25 - 6
modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3RetryingInputStream.java

@@ -77,7 +77,9 @@ class S3RetryingInputStream extends InputStream {
         this.failures = new ArrayList<>(MAX_SUPPRESSED_EXCEPTIONS);
         this.start = start;
         this.end = end;
+        final int initialAttempt = attempt;
         openStreamWithRetry();
+        maybeLogForSuccessAfterRetries(initialAttempt, "opened");
     }
 
     private void openStreamWithRetry() throws IOException {
@@ -130,14 +132,16 @@ class S3RetryingInputStream extends InputStream {
     @Override
     public int read() throws IOException {
         ensureOpen();
+        final int initialAttempt = attempt;
         while (true) {
             try {
                 final int result = currentStream.read();
                 if (result == -1) {
                     eof = true;
-                    return -1;
+                } else {
+                    currentOffset += 1;
                 }
-                currentOffset += 1;
+                maybeLogForSuccessAfterRetries(initialAttempt, "read");
                 return result;
             } catch (IOException e) {
                 reopenStreamOrFail(e);
@@ -148,14 +152,16 @@ class S3RetryingInputStream extends InputStream {
     @Override
     public int read(byte[] b, int off, int len) throws IOException {
         ensureOpen();
+        final int initialAttempt = attempt;
         while (true) {
             try {
                 final int bytesRead = currentStream.read(b, off, len);
                 if (bytesRead == -1) {
                     eof = true;
-                    return -1;
+                } else {
+                    currentOffset += bytesRead;
                 }
-                currentOffset += bytesRead;
+                maybeLogForSuccessAfterRetries(initialAttempt, "read");
                 return bytesRead;
             } catch (IOException e) {
                 reopenStreamOrFail(e);
@@ -192,8 +198,8 @@ class S3RetryingInputStream extends InputStream {
             throw finalException;
         }
 
-        // Log at info level for the 1st retry and every ~5 minutes afterward
-        logForRetry((attempt == 1 || attempt % 30 == 0) ? Level.INFO : Level.DEBUG, action, e);
+        // Log at info level for the 1st retry and then exponentially less
+        logForRetry(Integer.bitCount(attempt) == 1 ? Level.INFO : Level.DEBUG, action, e);
         if (failures.size() < MAX_SUPPRESSED_EXCEPTIONS) {
             failures.add(e);
         }
@@ -239,6 +245,19 @@ class S3RetryingInputStream extends InputStream {
         );
     }
 
+    private void maybeLogForSuccessAfterRetries(int initialAttempt, String action) {
+        if (attempt > initialAttempt) {
+            logger.info(
+                "successfully {} input stream for [{}/{}] with purpose [{}] after [{}] retries",
+                action,
+                blobStore.bucket(),
+                blobKey,
+                purpose,
+                attempt - initialAttempt
+            );
+        }
+    }
+
     private long currentStreamProgress() {
         return Math.subtractExact(Math.addExact(start, currentOffset), currentStreamFirstOffset);
     }