2626import java .util .Properties ;
2727import java .util .Set ;
2828import java .util .UUID ;
29+ import java .util .concurrent .CompletableFuture ;
2930import java .util .concurrent .Executors ;
3031import java .util .concurrent .ScheduledExecutorService ;
3132import java .util .concurrent .TimeUnit ;
@@ -110,7 +111,7 @@ private void startSubmitting(long initialDelay, long period, TimeUnit unit) {
110111 }
111112
112113 var enabled = Boolean .parseBoolean (System .getProperty ("faststats.enabled" , "true" ));
113-
114+
114115 if (!config .enabled () || !enabled ) {
115116 warn ("Metrics disabled, not starting submission" );
116117 return ;
@@ -128,21 +129,34 @@ private void startSubmitting(long initialDelay, long period, TimeUnit unit) {
128129 });
129130
130131 info ("Starting metrics submission" );
131- executor .scheduleAtFixedRate (this ::submitData , initialDelay , period , unit );
132+ executor .scheduleAtFixedRate (() -> {
133+ try {
134+ submitAsync ();
135+ } catch (Throwable t ) {
136+ error ("Failed to submit metrics" , t );
137+ }
138+ }, initialDelay , period , unit );
132139 }
133140
134141 protected boolean isSubmitting () {
135142 return executor != null && !executor .isShutdown ();
136143 }
137144
138- protected void submitData () {
145+ protected CompletableFuture < Boolean > submitAsync () throws IOException {
139146 var data = createData ().toString ();
140147 var bytes = data .getBytes (StandardCharsets .UTF_8 );
148+
149+ info ("Uncompressed data: " + data );
150+
141151 try (var byteOutput = new ByteArrayOutputStream ();
142152 var output = new GZIPOutputStream (byteOutput )) {
153+
143154 output .write (bytes );
144155 output .finish ();
156+
145157 var compressed = byteOutput .toByteArray ();
158+ info ("Compressed size: " + compressed .length + " bytes" );
159+
146160 var request = HttpRequest .newBuilder ()
147161 .POST (HttpRequest .BodyPublishers .ofByteArray (compressed ))
148162 .header ("Content-Encoding" , "gzip" )
@@ -154,31 +168,34 @@ protected void submitData() {
154168 .build ();
155169
156170 info ("Sending metrics to: " + url );
157- info ("Uncompressed data: " + data );
158- info ("Compressed size: " + compressed .length + " bytes" );
159-
160- var response = httpClient .send (request , HttpResponse .BodyHandlers .ofString (StandardCharsets .UTF_8 ));
161- var statusCode = response .statusCode ();
162- var body = response .body ();
163-
164- if (statusCode >= 200 && statusCode < 300 ) {
165- info ("Metrics submitted with status code: " + statusCode + " (" + body + ")" );
166- } else if (statusCode >= 300 && statusCode < 400 ) {
167- warn ("Received redirect response from metrics server: " + statusCode + " (" + body + ")" );
168- } else if (statusCode >= 400 && statusCode < 500 ) {
169- error ("Submitted invalid request to metrics server: " + statusCode + " (" + body + ")" , null );
170- } else if (statusCode >= 500 && statusCode < 600 ) {
171- error ("Received server error response from metrics server: " + statusCode + " (" + body + ")" , null );
172- } else {
173- warn ("Received unexpected response from metrics server: " + statusCode + " (" + body + ")" );
174- }
175-
176- } catch (HttpConnectTimeoutException e ) {
177- error ("Metrics submission timed out after 3 seconds: " + url , null );
178- } catch (ConnectException e ) {
179- error ("Failed to connect to metrics server: " + url , null );
180- } catch (Exception e ) {
181- error ("Failed to submit metrics" , e );
171+ return httpClient .sendAsync (request , HttpResponse .BodyHandlers .ofString (StandardCharsets .UTF_8 )).thenApply (response -> {
172+ var statusCode = response .statusCode ();
173+ var body = response .body ();
174+
175+ if (statusCode >= 200 && statusCode < 300 ) {
176+ info ("Metrics submitted with status code: " + statusCode + " (" + body + ")" );
177+ return true ;
178+ } else if (statusCode >= 300 && statusCode < 400 ) {
179+ warn ("Received redirect response from metrics server: " + statusCode + " (" + body + ")" );
180+ } else if (statusCode >= 400 && statusCode < 500 ) {
181+ error ("Submitted invalid request to metrics server: " + statusCode + " (" + body + ")" , null );
182+ } else if (statusCode >= 500 && statusCode < 600 ) {
183+ error ("Received server error response from metrics server: " + statusCode + " (" + body + ")" , null );
184+ } else {
185+ warn ("Received unexpected response from metrics server: " + statusCode + " (" + body + ")" );
186+ }
187+ return false ;
188+ }).exceptionally (throwable -> {
189+ var cause = throwable .getCause () != null ? throwable .getCause () : throwable ;
190+ if (cause instanceof HttpConnectTimeoutException ) {
191+ error ("Metrics submission timed out after 3 seconds: " + url , null );
192+ } else if (cause instanceof ConnectException ) {
193+ error ("Failed to connect to metrics server: " + url , null );
194+ } else {
195+ error ("Failed to submit metrics" , throwable );
196+ }
197+ return false ;
198+ });
182199 }
183200 }
184201
@@ -195,7 +212,7 @@ protected JsonObject createData() {
195212 this .charts .forEach (chart -> {
196213 try {
197214 chart .getData ().ifPresent (chartData -> charts .add (chart .getId (), chartData ));
198- } catch (Exception e ) {
215+ } catch (Throwable e ) {
199216 error ("Failed to build chart data: " + chart .getId (), e );
200217 }
201218 });
0 commit comments