Skip to content

Commit 58bbc19

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 58bbc19

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,11 +1,20 @@
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

79
public abstract boolean isLoggable(Level level);
810

11+
public void log(Level level, Throwable error, Supplier<String> message) {
12+
if (!isLoggable(level)) {
13+
return;
14+
}
15+
log(level, message.get(), error);
16+
}
17+
918
@Override
1019
public void debug(String message) {
1120
log(Level.DEBUG, message, null);
@@ -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);

0 commit comments

Comments
 (0)