Skip to content

Commit 38cc720

Browse files
committed
Add retry to GraphiteSender
- Add single retry to DGraphiteSender - Remove the unused Writer field from DGraphiteSender - Adjust down the log level to WARN when failing to report metrics
1 parent da4d5a6 commit 38cc720

File tree

3 files changed

+48
-28
lines changed

3 files changed

+48
-28
lines changed

metrics-graphite/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</parent>
99

1010
<artifactId>avaje-metrics-graphite</artifactId>
11+
<version>9.4-RC2</version>
1112

1213
<properties>
1314
<surefire.useModulePath>false</surefire.useModulePath>

metrics-graphite/src/main/java/io/avaje/metrics/graphite/DGraphiteReporter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
import java.io.IOException;
66
import java.util.List;
77

8-
import static java.lang.System.Logger.Level.DEBUG;
9-
import static java.lang.System.Logger.Level.ERROR;
8+
import static java.lang.System.Logger.Level.*;
109

1110
final class DGraphiteReporter implements GraphiteReporter {
1211

@@ -30,7 +29,7 @@ public void report() {
3029
}
3130
sender.flush();
3231
} catch (IOException e) {
33-
log.log(ERROR, "Error reporting metrics", e);
32+
log.log(WARNING, "Error reporting metrics", e);
3433
} finally {
3534
try {
3635
sender.close();

metrics-graphite/src/main/java/io/avaje/metrics/graphite/DGraphiteSender.java

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.avaje.metrics.graphite;
22

3+
import io.avaje.applog.AppLog;
34
import io.avaje.metrics.*;
45

56
import javax.net.SocketFactory;
@@ -11,13 +12,17 @@
1112
import java.util.List;
1213
import java.util.regex.Pattern;
1314

15+
import static java.lang.System.Logger.Level.INFO;
16+
import static java.lang.System.Logger.Level.WARNING;
1417
import static java.nio.charset.StandardCharsets.UTF_8;
1518

1619
/**
1720
* A client to a Carbon server that sends all metrics after they have been pickled in configurable sized batches
1821
*/
1922
final class DGraphiteSender implements GraphiteSender {
2023

24+
private static final System.Logger log = AppLog.getLogger(GraphiteReporter.class);
25+
2126
/**
2227
* Minimally necessary pickle opcodes.
2328
*/
@@ -40,7 +45,6 @@ final class DGraphiteSender implements GraphiteSender {
4045
private final String prefix;
4146
private final long timedThreshold;
4247
private Socket socket;
43-
private Writer writer;
4448

4549
DGraphiteSender(InetSocketAddress address, SocketFactory socketFactory, int batchSize, String prefix, long timedThreshold) {
4650
this.address = address;
@@ -56,7 +60,6 @@ public void connect() throws IOException {
5660
throw new IllegalStateException("Already connected");
5761
}
5862
this.socket = socketFactory.createSocket(address.getAddress(), address.getPort());
59-
this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), UTF_8));
6063
}
6164

6265
@Override
@@ -138,25 +141,27 @@ public void visit(GaugeLong.Stats gauge) {
138141
@Override
139142
public void flush() throws IOException {
140143
writeMetrics();
141-
if (writer != null) {
142-
writer.flush();
143-
}
144144
}
145145

146146
@Override
147-
public void close() throws IOException {
147+
public void close() {
148148
try {
149149
flush();
150-
if (writer != null) {
151-
writer.close();
152-
}
153-
} catch (IOException ex) {
154-
if (socket != null) {
150+
} catch (IOException e) {
151+
log.log(INFO, "Exception flushing metrics {0}", e);
152+
} finally {
153+
closeSocket();
154+
}
155+
}
156+
157+
private void closeSocket() {
158+
if (socket != null) {
159+
try {
155160
socket.close();
161+
} catch (IOException e) {
162+
log.log(INFO, "Exception trying to close socket {0}", e);
156163
}
157-
} finally {
158-
this.socket = null;
159-
this.writer = null;
164+
socket = null;
160165
}
161166
}
162167

@@ -168,13 +173,9 @@ public void close() throws IOException {
168173
private void writeMetrics() throws IOException {
169174
if (!metrics.isEmpty()) {
170175
try {
171-
byte[] payload = pickleMetrics(metrics);
172-
byte[] header = ByteBuffer.allocate(4).putInt(payload.length).array();
173-
174-
OutputStream outputStream = socket.getOutputStream();
175-
outputStream.write(header);
176-
outputStream.write(payload);
177-
outputStream.flush();
176+
final byte[] payload = pickleMetrics(metrics);
177+
final byte[] header = ByteBuffer.allocate(4).putInt(payload.length).array();
178+
send(header, payload);
178179
} finally {
179180
// if there was an error, we might miss some data. for now, drop those on the floor and
180181
// try to keep going.
@@ -183,6 +184,24 @@ private void writeMetrics() throws IOException {
183184
}
184185
}
185186

187+
private void send(byte[] header, byte[] payload) throws IOException {
188+
try {
189+
sendPayload(header, payload);
190+
} catch (IOException e) {
191+
log.log(WARNING, "Retry sending metrics due to {0}", e);
192+
closeSocket();
193+
this.socket = socketFactory.createSocket(address.getAddress(), address.getPort());
194+
sendPayload(header, payload);
195+
}
196+
}
197+
198+
private void sendPayload(byte[] header, byte[] payload) throws IOException {
199+
OutputStream outputStream = socket.getOutputStream();
200+
outputStream.write(header);
201+
outputStream.write(payload);
202+
outputStream.flush();
203+
}
204+
186205
/**
187206
* See: <a href="http://readthedocs.org/docs/graphite/en/1.0/feeding-carbon.html">feeding-carbon</a>
188207
*/
@@ -247,10 +266,11 @@ public String sanitize(String string) {
247266
return WHITESPACE.matcher(string.trim()).replaceAll(DASH);
248267
}
249268

250-
static class MetricTuple {
251-
long timestamp;
252-
String value;
253-
String[] names;
269+
static final class MetricTuple {
270+
271+
final long timestamp;
272+
final String value;
273+
final String[] names;
254274

255275
MetricTuple(long timestamp, String value, String... names) {
256276
this.timestamp = timestamp;

0 commit comments

Comments
 (0)