diff --git a/CHANGELOG.md b/CHANGELOG.md index 5718c86cfd5..802fae4336e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 1.13.0 [unreleased] +### Features +1. [#163](https://github.com/influxdata/influxdb-client-java/pull/163): Improved logging message for retries + ## 1.12.0 [2020-10-02] ### Features diff --git a/client/src/main/java/com/influxdb/client/internal/AbstractWriteClient.java b/client/src/main/java/com/influxdb/client/internal/AbstractWriteClient.java index 73db523d03f..5fa8e42e939 100644 --- a/client/src/main/java/com/influxdb/client/internal/AbstractWriteClient.java +++ b/client/src/main/java/com/influxdb/client/internal/AbstractWriteClient.java @@ -520,7 +520,7 @@ private Function, Publisher> retryHandler(@Nonnull final long retryInterval = attempt.getRetryInterval(); - publish(new WriteRetriableErrorEvent(throwable, retryInterval)); + publish(new WriteRetriableErrorEvent(toInfluxException(throwable), retryInterval)); return Flowable.just("notify").delay(retryInterval, TimeUnit.MILLISECONDS, retryScheduler); } diff --git a/client/src/main/java/com/influxdb/client/write/events/WriteRetriableErrorEvent.java b/client/src/main/java/com/influxdb/client/write/events/WriteRetriableErrorEvent.java index ab4e2056340..ba1acdca891 100644 --- a/client/src/main/java/com/influxdb/client/write/events/WriteRetriableErrorEvent.java +++ b/client/src/main/java/com/influxdb/client/write/events/WriteRetriableErrorEvent.java @@ -66,8 +66,9 @@ public Long getRetryInterval() { } @Override + @SuppressWarnings("MagicNumber") public void logEvent() { - String msg = "The retriable error occurred during writing of data. Retry in: {0} [ms]"; - LOG.log(Level.WARNING, msg, retryInterval); + String msg = "The retriable error occurred during writing of data. Reason: ''{0}''. Retry in: {1}s."; + LOG.log(Level.WARNING, msg, new Object[]{throwable.getMessage(), (double) retryInterval / 1000}); } } \ No newline at end of file diff --git a/client/src/test/java/com/influxdb/client/ITQueryService.java b/client/src/test/java/com/influxdb/client/ITQueryService.java index 6681d700ac5..6df46c00787 100644 --- a/client/src/test/java/com/influxdb/client/ITQueryService.java +++ b/client/src/test/java/com/influxdb/client/ITQueryService.java @@ -41,7 +41,6 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; @@ -155,13 +154,10 @@ void suggestions() throws IOException { FluxSuggestion suggestion = queryService.getQuerySuggestionsName("range", null).execute().body(); Assertions.assertThat(suggestion).isNotNull(); Assertions.assertThat(suggestion.getParams()) - .hasSize(6) + .hasSize(3) .hasEntrySatisfying("start", value -> Assertions.assertThat(value).isEqualTo("invalid")) - .hasEntrySatisfying("startColumn", value -> Assertions.assertThat(value).isEqualTo("string")) .hasEntrySatisfying("stop", value -> Assertions.assertThat(value).isEqualTo("invalid")) - .hasEntrySatisfying("stopColumn", value -> Assertions.assertThat(value).isEqualTo("string")) - .hasEntrySatisfying("tables", value -> Assertions.assertThat(value).isEqualTo("array")) - .hasEntrySatisfying("timeColumn", value -> Assertions.assertThat(value).isEqualTo("string")); + .hasEntrySatisfying("tables", value -> Assertions.assertThat(value).isEqualTo("array")); } } \ No newline at end of file diff --git a/client/src/test/java/com/influxdb/client/MockLogHandler.java b/client/src/test/java/com/influxdb/client/MockLogHandler.java new file mode 100644 index 00000000000..208e971f5c9 --- /dev/null +++ b/client/src/test/java/com/influxdb/client/MockLogHandler.java @@ -0,0 +1,57 @@ +/* + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.influxdb.client; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * @author Jakub Bednar (12/10/2020 13:49) + */ +public class MockLogHandler extends Handler { + private final Map> levels = new HashMap<>(); + + @Override + public void publish(final LogRecord record) { + List records = levels.computeIfAbsent(record.getLevel(), level -> new ArrayList<>()); + records.add(record); + } + + @Override + public void flush() { + + } + + @Override + public void close() throws SecurityException { + + } + + public List getRecords(Level level) { + return levels.get(level); + } +} diff --git a/client/src/test/java/com/influxdb/client/WriteApiTest.java b/client/src/test/java/com/influxdb/client/WriteApiTest.java index f8448297d7f..95144854891 100644 --- a/client/src/test/java/com/influxdb/client/WriteApiTest.java +++ b/client/src/test/java/com/influxdb/client/WriteApiTest.java @@ -26,6 +26,9 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; import javax.annotation.Nonnull; import com.influxdb.annotations.Column; @@ -53,7 +56,6 @@ import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; -import retrofit2.HttpException; /** * @author Jakub Bednar (bednar@github) (21/09/2018 11:36) @@ -646,8 +648,8 @@ void retryWithRetryAfter() throws InterruptedException { retriableListener.awaitCount(1); Assertions.assertThat(retriableListener.getValue().getThrowable()) - .isInstanceOf(HttpException.class) - .hasMessage("HTTP 429 Client Error"); + .isInstanceOf(InfluxException.class) + .hasMessage("token is temporarily over quota"); Assertions.assertThat(retriableListener.getValue().getRetryInterval()).isEqualTo(5000); @@ -748,6 +750,40 @@ void retryOnNetworkError() throws IOException, InterruptedException { retriableListener.awaitCount(3); } + @Test + public void retryContainsMessage() { + + MockLogHandler handler = new MockLogHandler(); + + final Logger logger = Logger.getLogger(WriteRetriableErrorEvent.class.getName()); + logger.addHandler(handler); + + MockResponse errorResponse = new MockResponse() + .setResponseCode(429) + .addHeader("Retry-After", 5) + .setBody("{\"code\":\"too many requests\",\"message\":\"org 04014de4ed590000 has exceeded limited_write plan limit\"}"); + mockServer.enqueue(errorResponse); + mockServer.enqueue(createResponse("{}")); + + writeApi = influxDBClient.getWriteApi(WriteOptions.builder().batchSize(1).build()); + + WriteEventListener listener = new WriteEventListener<>(); + writeApi.listenEvents(WriteRetriableErrorEvent.class, listener); + + writeApi.writePoint("b1", "org1", Point.measurement("h2o").addTag("location", "europe").addField("level", 2)); + + listener.awaitCount(1); + + List records = handler.getRecords(Level.WARNING); + + Assertions.assertThat(records).hasSize(1); + Assertions.assertThat(records.get(0).getMessage()) + .isEqualTo("The retriable error occurred during writing of data. Reason: ''{0}''. Retry in: {1}s."); + Assertions.assertThat(records.get(0).getParameters()).hasSize(2); + Assertions.assertThat(records.get(0).getParameters()[0]).isEqualTo("org 04014de4ed590000 has exceeded limited_write plan limit"); + Assertions.assertThat(records.get(0).getParameters()[1]).isEqualTo(5.0); + } + @Test void parametersFromOptions() throws InterruptedException, IOException { diff --git a/client/src/test/java/com/influxdb/client/internal/WaitToConditionTest.java b/client/src/test/java/com/influxdb/client/internal/WaitToConditionTest.java index 14bc9492d09..f8f3871e980 100644 --- a/client/src/test/java/com/influxdb/client/internal/WaitToConditionTest.java +++ b/client/src/test/java/com/influxdb/client/internal/WaitToConditionTest.java @@ -21,11 +21,13 @@ */ package com.influxdb.client.internal; -import java.util.ArrayList; import java.util.List; -import java.util.logging.Handler; +import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; +import java.util.stream.Collectors; + +import com.influxdb.client.MockLogHandler; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -41,29 +43,19 @@ class WaitToConditionTest { @Test public void waitToCondition() { - List records = new ArrayList<>(); - + MockLogHandler handler = new MockLogHandler(); + final Logger logger = Logger.getLogger(AbstractWriteClient.class.getName()); - logger.addHandler(new Handler() { - @Override - public void publish(final LogRecord record) { - records.add(record.getMessage()); - } - - @Override - public void flush() { - - } - - @Override - public void close() throws SecurityException { - - } - }); + logger.addHandler(handler); AbstractWriteClient.waitToCondition(() -> true, 30000); AbstractWriteClient.waitToCondition(() -> false, 1); + List records = handler.getRecords(Level.SEVERE) + .stream() + .map(LogRecord::getMessage) + .collect(Collectors.toList()); + Assertions.assertThat(records).contains("The WriteApi can't be gracefully dispose! - 1ms elapsed."); Assertions.assertThat(records).doesNotContain("The WriteApi can't be gracefully dispose! - 30000ms elapsed."); }