34
34
import java .net .*;
35
35
import java .security .cert .Certificate ;
36
36
import java .security .cert .X509Certificate ;
37
+ import java .util .concurrent .atomic .AtomicInteger ;
37
38
import java .util .logging .Level ;
38
39
39
40
/**
44
45
@ ThreadSafe
45
46
public class TcpSyslogMessageSender extends AbstractSyslogMessageSender {
46
47
public final static int SETTING_SOCKET_CONNECT_TIMEOUT_IN_MILLIS_DEFAULT_VALUE = 500 ;
48
+ public final static int SETTING_MAX_RETRY = 2 ;
47
49
48
50
/**
49
51
* {@link java.net.InetAddress InetAddress} of the remote Syslog Server.
@@ -64,28 +66,51 @@ public class TcpSyslogMessageSender extends AbstractSyslogMessageSender {
64
66
private Writer writer ;
65
67
private int socketConnectTimeoutInMillis = SETTING_SOCKET_CONNECT_TIMEOUT_IN_MILLIS_DEFAULT_VALUE ;
66
68
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 ();
68
77
69
78
@ Override
70
79
public synchronized void sendMessage (@ Nonnull SyslogMessage message ) throws IOException {
71
- ensureSyslogServerConnection ();
72
80
sendCounter .incrementAndGet ();
73
81
long nanosBefore = System .nanoTime ();
74
82
75
83
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
+ }
78
113
}
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 ;
89
114
} finally {
90
115
sendDurationInNanosCounter .addAndGet (System .nanoTime () - nanosBefore );
91
116
}
@@ -191,4 +216,36 @@ public boolean isSsl() {
191
216
public void setSsl (boolean ssl ) {
192
217
this .ssl = ssl ;
193
218
}
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
+ }
194
251
}
0 commit comments