Skip to content

Commit d94d684

Browse files
Add retry mechanism to handle failure of the tcp connection between the Syslog Client and the Syslog server. Fix #2.
1 parent 6ef7f53 commit d94d684

File tree

3 files changed

+87
-15
lines changed

3 files changed

+87
-15
lines changed

src/main/java/com/cloudbees/syslog/sender/AbstractSyslogMessageSender.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,18 @@ public void setMessageFormat(MessageFormat messageFormat) {
133133
public void setDefaultSeverity(Severity defaultSeverity) {
134134
this.defaultSeverity = defaultSeverity;
135135
}
136+
137+
@Override
138+
public String toString() {
139+
return "AbstractSyslogMessageSender{" +
140+
"defaultAppName='" + defaultAppName + '\'' +
141+
", defaultFacility=" + defaultFacility +
142+
", defaultMessageHostname='" + defaultMessageHostname + '\'' +
143+
", defaultSeverity=" + defaultSeverity +
144+
", messageFormat=" + messageFormat +
145+
", sendCounter=" + sendCounter +
146+
", sendDurationInNanosCounter=" + sendDurationInNanosCounter +
147+
", sendErrorCounter=" + sendErrorCounter +
148+
'}';
149+
}
136150
}

src/main/java/com/cloudbees/syslog/sender/TcpSyslogMessageSender.java

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.net.*;
3535
import java.security.cert.Certificate;
3636
import java.security.cert.X509Certificate;
37+
import java.util.concurrent.atomic.AtomicInteger;
3738
import java.util.logging.Level;
3839

3940
/**
@@ -44,6 +45,7 @@
4445
@ThreadSafe
4546
public class TcpSyslogMessageSender extends AbstractSyslogMessageSender {
4647
public final static int SETTING_SOCKET_CONNECT_TIMEOUT_IN_MILLIS_DEFAULT_VALUE = 500;
48+
public final static int SETTING_MAX_RETRY = 2;
4749

4850
/**
4951
* {@link java.net.InetAddress InetAddress} of the remote Syslog Server.
@@ -64,28 +66,51 @@ public class TcpSyslogMessageSender extends AbstractSyslogMessageSender {
6466
private Writer writer;
6567
private int socketConnectTimeoutInMillis = SETTING_SOCKET_CONNECT_TIMEOUT_IN_MILLIS_DEFAULT_VALUE;
6668
private boolean ssl;
67-
69+
/**
70+
* Number of retries to send a message before throwing an exception.
71+
*/
72+
private int maxRetryCount = SETTING_MAX_RETRY;
73+
/**
74+
* Number of exceptions trying to send message.
75+
*/
76+
protected final AtomicInteger trySendErrorCounter = new AtomicInteger();
6877

6978
@Override
7079
public synchronized void sendMessage(@Nonnull SyslogMessage message) throws IOException {
71-
ensureSyslogServerConnection();
7280
sendCounter.incrementAndGet();
7381
long nanosBefore = System.nanoTime();
7482

7583
try {
76-
if (logger.isLoggable(Level.FINEST)) {
77-
logger.finest("Send syslog message " + message.toSyslogMessage(messageFormat));
84+
Exception lastException = null;
85+
for (int i = 0; i <= maxRetryCount; i++) {
86+
try {
87+
if (logger.isLoggable(Level.FINEST)) {
88+
logger.finest("Send syslog message " + message.toSyslogMessage(messageFormat));
89+
}
90+
ensureSyslogServerConnection();
91+
message.toSyslogMessage(messageFormat, writer);
92+
// use the CR LF non transparent framing as described in "3.4.2. Non-Transparent-Framing"
93+
writer.write("\r\n");
94+
writer.flush();
95+
return;
96+
} catch (IOException e) {
97+
lastException = e;
98+
IoUtils.closeQuietly(socket, writer);
99+
trySendErrorCounter.incrementAndGet();
100+
} catch (RuntimeException e) {
101+
lastException = e;
102+
IoUtils.closeQuietly(socket, writer);
103+
trySendErrorCounter.incrementAndGet();
104+
}
105+
}
106+
if (lastException != null) {
107+
sendErrorCounter.incrementAndGet();
108+
if (lastException instanceof IOException) {
109+
throw (IOException) lastException;
110+
} else if (lastException instanceof RuntimeException) {
111+
throw (RuntimeException) lastException;
112+
}
78113
}
79-
message.toSyslogMessage(messageFormat, writer);
80-
// use the CR LF non transparent framing as described in "3.4.2. Non-Transparent-Framing"
81-
writer.write("\r\n");
82-
writer.flush();
83-
} catch (IOException e) {
84-
sendErrorCounter.incrementAndGet();
85-
throw e;
86-
} catch (RuntimeException e) {
87-
sendErrorCounter.incrementAndGet();
88-
throw e;
89114
} finally {
90115
sendDurationInNanosCounter.addAndGet(System.nanoTime() - nanosBefore);
91116
}
@@ -191,4 +216,36 @@ public boolean isSsl() {
191216
public void setSsl(boolean ssl) {
192217
this.ssl = ssl;
193218
}
219+
220+
public int getSocketConnectTimeoutInMillis() {
221+
return socketConnectTimeoutInMillis;
222+
}
223+
224+
public int getMaxRetryCount() {
225+
return maxRetryCount;
226+
}
227+
228+
public int getTrySendErrorCounter() {
229+
return trySendErrorCounter.get();
230+
}
231+
232+
@Override
233+
public String toString() {
234+
return "TcpSyslogMessageSender{" +
235+
"syslogServerHostname='" + this.getSyslogServerHostname() + '\'' +
236+
", syslogServerPort='" + this.getSyslogServerPort() + '\'' +
237+
", ssl=" + ssl +
238+
", maxRetryCount=" + maxRetryCount +
239+
", socketConnectTimeoutInMillis=" + socketConnectTimeoutInMillis +
240+
", defaultAppName='" + defaultAppName + '\'' +
241+
", defaultFacility=" + defaultFacility +
242+
", defaultMessageHostname='" + defaultMessageHostname + '\'' +
243+
", defaultSeverity=" + defaultSeverity +
244+
", messageFormat=" + messageFormat +
245+
", sendCounter=" + sendCounter +
246+
", sendDurationInNanosCounter=" + sendDurationInNanosCounter +
247+
", sendErrorCounter=" + sendErrorCounter +
248+
", trySendErrorCounter=" + trySendErrorCounter +
249+
'}';
250+
}
194251
}

src/test/java/com/cloudbees/syslog/sender/TcpSyslogMessageSenderTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
*/
3030
public class TcpSyslogMessageSenderTest {
3131

32-
@Ignore
32+
// @Ignore
3333
@Test
3434
public void send() throws Exception {
3535
TcpSyslogMessageSender messageSender = new TcpSyslogMessageSender();
@@ -40,6 +40,7 @@ public void send() throws Exception {
4040
messageSender.setSyslogServerHostname("logs2.papertrailapp.com");
4141
messageSender.setSyslogServerPort(46022);
4242
messageSender.setMessageFormat(MessageFormat.RFC_3164);
43+
messageSender.setSsl(true);
4344
messageSender.sendMessage("unit test message over tcp éèà " + getClass() + " - " + new Timestamp(System.currentTimeMillis()));
4445
}
4546

0 commit comments

Comments
 (0)