Skip to content

Commit 20faf42

Browse files
committed
Logging of client reconnects and transient errors
Add logging waring messages when client tries establishing connection to Tarantool instance. All the request that cannot be processed because of some transient errors are also traced. Disable JUL logging for test classes by default. Follows on: #194
1 parent 633f28a commit 20faf42

File tree

10 files changed

+188
-31
lines changed

10 files changed

+188
-31
lines changed

pom.xml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23
<modelVersion>4.0.0</modelVersion>
34

45
<groupId>org.tarantool</groupId>
@@ -12,6 +13,7 @@
1213
<mockito.version>1.10.19</mockito.version>
1314
<!-- logger dependency versions -->
1415
<sfl4j.version>1.7.26</sfl4j.version>
16+
<project.testResources>${project.basedir}/src/test/resources</project.testResources>
1517
</properties>
1618
<name>Tarantool Connector for Java</name>
1719
<url>https://github.com/tarantool/tarantool-java</url>
@@ -73,17 +75,24 @@
7375
<artifactId>templating-maven-plugin</artifactId>
7476
<version>1.0.0</version>
7577
<executions>
76-
<execution>
77-
<id>filter-src</id>
78-
<goals>
79-
<goal>filter-sources</goal>
80-
</goals>
81-
</execution>
78+
<execution>
79+
<id>filter-src</id>
80+
<goals>
81+
<goal>filter-sources</goal>
82+
</goals>
83+
</execution>
8284
</executions>
8385
</plugin>
8486
<plugin>
8587
<artifactId>maven-surefire-plugin</artifactId>
8688
<version>3.0.0-M3</version>
89+
<configuration>
90+
<systemPropertyVariables>
91+
<java.util.logging.config.file>
92+
${project.testResources}/jul-silent.properties
93+
</java.util.logging.config.file>
94+
</systemPropertyVariables>
95+
</configuration>
8796
</plugin>
8897
<plugin>
8998
<groupId>org.apache.maven.plugins</groupId>
@@ -99,6 +108,12 @@
99108
</executions>
100109
<configuration>
101110
<trimStackTrace>false</trimStackTrace>
111+
<systemPropertyVariables>
112+
<java.util.logging.config.file>
113+
${project.testResources}/jul-silent.properties
114+
</java.util.logging.config.file>
115+
</systemPropertyVariables>
116+
102117
</configuration>
103118
</plugin>
104119
<plugin>

src/main/java/org/tarantool/RoundRobinSocketProviderImpl.java

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.concurrent.locks.Lock;
1414
import java.util.concurrent.locks.ReadWriteLock;
1515
import java.util.concurrent.locks.ReentrantReadWriteLock;
16+
import java.util.function.Supplier;
1617
import java.util.stream.Collectors;
1718

1819
/**
@@ -93,13 +94,7 @@ private void updateAddressList(Collection<String> addresses) {
9394
* @return socket addresses
9495
*/
9596
public List<SocketAddress> getAddresses() {
96-
Lock readLock = addressListLock.readLock();
97-
readLock.lock();
98-
try {
99-
return Collections.unmodifiableList(this.socketAddresses);
100-
} finally {
101-
readLock.unlock();
102-
}
97+
return readGuard(() -> Collections.unmodifiableList(this.socketAddresses));
10398
}
10499

105100
/**
@@ -109,14 +104,10 @@ public List<SocketAddress> getAddresses() {
109104
* if {@link #currentPosition} has {@link #UNSET_POSITION} value
110105
*/
111106
protected InetSocketAddress getLastObtainedAddress() {
112-
Lock readLock = addressListLock.readLock();
113-
readLock.lock();
114-
try {
107+
return readGuard(() -> {
115108
int index = currentPosition.get();
116109
return index != UNSET_POSITION ? socketAddresses.get(index) : null;
117-
} finally {
118-
readLock.unlock();
119-
}
110+
});
120111
}
121112

122113
/**
@@ -176,13 +167,7 @@ public void setRetriesLimit(int retriesLimit) {
176167
* @return Number of configured addresses.
177168
*/
178169
protected int getAddressCount() {
179-
Lock readLock = addressListLock.readLock();
180-
readLock.lock();
181-
try {
182-
return socketAddresses.size();
183-
} finally {
184-
readLock.unlock();
185-
}
170+
return readGuard(socketAddresses::size);
186171
}
187172

188173
/**
@@ -191,11 +176,25 @@ protected int getAddressCount() {
191176
* @return Socket address to use for the next reconnection attempt
192177
*/
193178
protected InetSocketAddress getNextSocketAddress() {
179+
return readGuard(() -> {
180+
int position = currentPosition.updateAndGet(i -> (i + 1) % socketAddresses.size());
181+
return socketAddresses.get(position);
182+
});
183+
}
184+
185+
@Override
186+
public SocketAddress getAddress() {
187+
return readGuard(() -> {
188+
int position = currentPosition.get() + 1 % socketAddresses.size();
189+
return socketAddresses.get(position);
190+
});
191+
}
192+
193+
private <R> R readGuard(Supplier<R> supplier) {
194194
Lock readLock = addressListLock.readLock();
195195
readLock.lock();
196196
try {
197-
int position = currentPosition.updateAndGet(i -> (i + 1) % socketAddresses.size());
198-
return socketAddresses.get(position);
197+
return supplier.get();
199198
} finally {
200199
readLock.unlock();
201200
}

src/main/java/org/tarantool/SingleSocketChannelProviderImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public SingleSocketChannelProviderImpl(String address) {
2424
setAddress(address);
2525
}
2626

27+
@Override
2728
public SocketAddress getAddress() {
2829
return address;
2930
}

src/main/java/org/tarantool/SocketChannelProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,15 @@ public interface SocketChannelProvider {
1919
*/
2020
SocketChannel get(int retryNumber, Throwable lastError);
2121

22+
/**
23+
* Gets an address that will be used when
24+
* {@link #get(int, Throwable)} is invoked.
25+
*
26+
* @return effective address or {@literal null}
27+
* if it cannot be calculated in advance.
28+
*/
29+
default SocketAddress getAddress() {
30+
return null;
31+
}
32+
2233
}

src/main/java/org/tarantool/TarantoolClientImpl.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package org.tarantool;
22

3+
import org.tarantool.logging.Logger;
4+
import org.tarantool.logging.LoggerFactory;
35
import org.tarantool.protocol.ProtoUtils;
46
import org.tarantool.protocol.ReadableViaSelectorChannel;
57
import org.tarantool.protocol.TarantoolGreeting;
68
import org.tarantool.protocol.TarantoolPacket;
9+
import org.tarantool.util.StringUtils;
710

811
import java.io.IOException;
912
import java.nio.ByteBuffer;
1013
import java.nio.channels.SocketChannel;
14+
import java.util.Arrays;
1115
import java.util.Iterator;
1216
import java.util.List;
1317
import java.util.Map;
@@ -28,6 +32,8 @@
2832

2933
public class TarantoolClientImpl extends TarantoolBase<Future<?>> implements TarantoolClient {
3034

35+
private static final Logger LOGGER = LoggerFactory.getLogger(TarantoolClientImpl.class);
36+
3137
public static final CommunicationException NOT_INIT_EXCEPTION
3238
= new CommunicationException("Not connected, initializing connection");
3339

@@ -147,6 +153,12 @@ protected void reconnect(Throwable lastError) {
147153
int retryNumber = 0;
148154
while (!Thread.currentThread().isInterrupted()) {
149155
try {
156+
if (lastError != NOT_INIT_EXCEPTION) {
157+
LOGGER.warn(() -> "Attempt to (re-)connect to Tarantool instance " +
158+
(StringUtils.isBlank(config.username) ? "" : config.username + ":*****@") +
159+
socketProvider.getAddress().toString(), lastError
160+
);
161+
}
150162
channel = socketProvider.get(retryNumber++, lastError == NOT_INIT_EXCEPTION ? null : lastError);
151163
} catch (Exception e) {
152164
closeChannel(channel);
@@ -714,6 +726,15 @@ public Object[] getArgs() {
714726
return args;
715727
}
716728

729+
@Override
730+
public String toString() {
731+
return "TarantoolOp{" +
732+
"id=" + id +
733+
", code=" + code +
734+
", args=" + Arrays.toString(args) +
735+
'}';
736+
}
737+
717738
/**
718739
* Missed in jdk8 CompletableFuture operator to limit execution
719740
* by time.

src/main/java/org/tarantool/TarantoolClusterClient.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import org.tarantool.cluster.TarantoolClusterDiscoverer;
44
import org.tarantool.cluster.TarantoolClusterStoredFunctionDiscoverer;
5+
import org.tarantool.logging.Logger;
6+
import org.tarantool.logging.LoggerFactory;
57
import org.tarantool.protocol.TarantoolPacket;
68
import org.tarantool.util.StringUtils;
79

@@ -27,6 +29,8 @@
2729
*/
2830
public class TarantoolClusterClient extends TarantoolClientImpl {
2931

32+
private static final Logger LOGGER = LoggerFactory.getLogger(TarantoolClusterClient.class);
33+
3034
/**
3135
* Need some execution context to retry writes.
3236
*/
@@ -153,6 +157,7 @@ protected boolean checkFail(TarantoolOp<?> future, Exception e) {
153157
} else {
154158
assert retries != null;
155159
retries.put(future.getId(), future);
160+
LOGGER.trace("Request {0} was delayed because of {1}", future, e);
156161
return false;
157162
}
158163
}
@@ -194,13 +199,18 @@ protected void onReconnect() {
194199
// First call is before the constructor finished. Skip it.
195200
return;
196201
}
197-
Collection<TarantoolOp<?>> futuresToRetry = new ArrayList<>(retries.values());
202+
Collection<TarantoolOp<?>> delayed = new ArrayList<>(retries.values());
203+
Collection<TarantoolOp<?>> reissued = new ArrayList<>(retries.size());
198204
retries.clear();
199-
for (final TarantoolOp<?> future : futuresToRetry) {
205+
for (final TarantoolOp<?> future : delayed) {
200206
if (!future.isDone()) {
201207
executor.execute(() -> registerOperation(future));
208+
reissued.add(future);
202209
}
203210
}
211+
for (final TarantoolOp<?> future : reissued) {
212+
LOGGER.trace("{0} was re-issued after reconnection", future);
213+
}
204214
}
205215

206216
@Override

src/main/java/org/tarantool/logging/BaseLogger.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
package org.tarantool.logging;
22

3+
import java.util.function.Supplier;
4+
35
abstract class BaseLogger implements Logger {
46

57
public abstract void log(Level level, String text, Throwable error, Object... parameters);
68

9+
public void log(Level level, Throwable error, Supplier<String> message) {
10+
if (!isLoggable(level)) {
11+
return;
12+
}
13+
log(level, message.get(), error);
14+
}
15+
716
public abstract boolean isLoggable(Level level);
817

918
@Override
@@ -21,6 +30,11 @@ public void debug(String message, Throwable throwable) {
2130
log(Level.DEBUG, message, throwable);
2231
}
2332

33+
@Override
34+
public void debug(Supplier<String> message, Throwable throwable) {
35+
log(Level.DEBUG, throwable, message);
36+
}
37+
2438
@Override
2539
public void error(String message) {
2640
log(Level.ERROR, message, null);
@@ -36,6 +50,11 @@ public void error(String message, Throwable throwable) {
3650
log(Level.ERROR, message, throwable);
3751
}
3852

53+
@Override
54+
public void error(Supplier<String> message, Throwable throwable) {
55+
log(Level.ERROR, throwable, message);
56+
}
57+
3958
@Override
4059
public void info(String message) {
4160
log(Level.INFO, message, null);
@@ -51,6 +70,11 @@ public void info(String message, Throwable throwable) {
5170
log(Level.INFO, message, throwable);
5271
}
5372

73+
@Override
74+
public void info(Supplier<String> message, Throwable throwable) {
75+
log(Level.INFO, throwable, message);
76+
}
77+
5478
@Override
5579
public void trace(String message) {
5680
log(Level.TRACE, message, null);
@@ -66,6 +90,11 @@ public void trace(String message, Throwable throwable) {
6690
log(Level.TRACE, message, throwable);
6791
}
6892

93+
@Override
94+
public void trace(Supplier<String> message, Throwable throwable) {
95+
log(Level.TRACE, throwable, message);
96+
}
97+
6998
@Override
7099
public void warn(String message) {
71100
log(Level.WARN, message, null);
@@ -81,6 +110,11 @@ public void warn(String message, Throwable throwable) {
81110
log(Level.WARN, message, throwable);
82111
}
83112

113+
@Override
114+
public void warn(Supplier<String> message, Throwable throwable) {
115+
log(Level.TRACE, throwable, message);
116+
}
117+
84118
@Override
85119
public boolean isDebugEnabled() {
86120
return isLoggable(Level.DEBUG);

src/main/java/org/tarantool/logging/Logger.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.tarantool.logging;
22

3+
import java.util.function.Supplier;
4+
35
/**
46
* Minimal logger contract to perform internal
57
* logging.
@@ -26,6 +28,8 @@ enum Level {
2628

2729
void error(final String message, Throwable throwable);
2830

31+
void error(final Supplier<String> message, Throwable throwable);
32+
2933
boolean isWarnEnabled();
3034

3135
void warn(final String message);
@@ -34,6 +38,8 @@ enum Level {
3438

3539
void warn(final String message, Throwable throwable);
3640

41+
void warn(final Supplier<String> message, Throwable throwable);
42+
3743
boolean isInfoEnabled();
3844

3945
void info(final String message);
@@ -42,6 +48,8 @@ enum Level {
4248

4349
void info(final String message, Throwable throwable);
4450

51+
void info(final Supplier<String> message, Throwable throwable);
52+
4553
boolean isDebugEnabled();
4654

4755
void debug(final String message);
@@ -50,6 +58,8 @@ enum Level {
5058

5159
void debug(final String message, Throwable throwable);
5260

61+
void debug(final Supplier<String> message, Throwable throwable);
62+
5363
boolean isTraceEnabled();
5464

5565
void trace(final String message);
@@ -58,4 +68,6 @@ enum Level {
5868

5969
void trace(final String message, Throwable throwable);
6070

71+
void trace(final Supplier<String> message, Throwable throwable);
72+
6173
}

0 commit comments

Comments
 (0)