/** Test that if all 'marks' are timeouts that it will trip the circuit. */ @Test public void testTripCircuitOnTimeouts() { String key = "cmd-D"; try { HystrixCommand<Boolean> cmd1 = new TimeoutCommand(key); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); // success with high latency cmd1.execute(); HystrixCommand<Boolean> cmd2 = new TimeoutCommand(key); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new TimeoutCommand(key); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key); cmd4.execute(); // everything has been a timeout so we should not allow any requests Thread.sleep(100); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** * When volume of reporting during a statistical window is lower than a defined threshold the * circuit will not trip regardless of whatever statistics are calculated. */ @Test public void testLowVolumeDoesNotTripCircuit() { String key = "cmd-I"; try { int sleepWindow = 200; int lowVolume = 5; HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60, sleepWindow, lowVolume); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); cmd1.execute(); HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow, lowVolume); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow, lowVolume); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new FailureCommand(key, 1, sleepWindow, lowVolume); cmd4.execute(); // even though it has all failed we won't trip the circuit because the volume is low Thread.sleep(100); assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** * Test that an open circuit is closed after 1 success. This also ensures that the rolling window * (containing failures) is cleared after the sleep window Otherwise, the next bucket roll would * produce another signal to fail unless it is explicitly cleared (via {@link * HystrixCommandMetrics#resetStream()}. */ @Test public void testCircuitClosedAfterSuccess() { String key = "cmd-G"; try { int sleepWindow = 20; HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 1, sleepWindow); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); cmd1.execute(); HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1, sleepWindow); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1, sleepWindow); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key, sleepWindow); cmd4.execute(); // everything has failed in the test window so we should return false now Thread.sleep(100); System.out.println( "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString()); System.out.println("CircuitBreaker state 1 : " + cmd1.getMetrics().getHealthCounts()); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); // wait for sleepWindow to pass Thread.sleep(sleepWindow + 50); // but the circuit should still be open assertTrue(cb.isOpen()); // we should now allow 1 request, and upon success, should cause the circuit to be closed HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 60, sleepWindow); Observable<Boolean> asyncResult = cmd5.observe(); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); asyncResult.toBlocking().single(); // all requests should be open again System.out.println("CircuitBreaker state 2 : " + cmd1.getMetrics().getHealthCounts()); assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); // and the circuit should be closed again assertFalse(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** Test that if the % of failures is higher than the threshold that the circuit trips. */ @Test public void testCircuitDoesNotTripOnFailuresBelowThreshold() { String key = "cmd-C"; try { HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 60); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); // success with high latency cmd1.execute(); HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1); cmd4.execute(); HystrixCommand<Boolean> cmd5 = new SuccessCommand(key, 1); cmd5.execute(); HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 1); cmd6.execute(); HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 1); cmd7.execute(); HystrixCommand<Boolean> cmd8 = new FailureCommand(key, 1); cmd8.execute(); // this should remain closed as the failure threshold is below the percentage limit Thread.sleep(100); System.out.println( "ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString()); System.out.println("Current CircuitBreaker Status : " + cmd1.getMetrics().getHealthCounts()); assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** * Test that if all 'marks' are successes during the test window that it does NOT trip the * circuit. Test that if all 'marks' are failures during the test window that it trips the * circuit. */ @Test public void testTripCircuit() { String key = "cmd-A"; try { HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 1); HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1); HystrixCommand<Boolean> cmd3 = new SuccessCommand(key, 1); HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1); HystrixCircuitBreaker cb = cmd1.circuitBreaker; cmd1.execute(); cmd2.execute(); cmd3.execute(); cmd4.execute(); // this should still allow requests as everything has been successful Thread.sleep(100); assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); // fail HystrixCommand<Boolean> cmd5 = new FailureCommand(key, 1); HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 1); HystrixCommand<Boolean> cmd7 = new FailureCommand(key, 1); HystrixCommand<Boolean> cmd8 = new FailureCommand(key, 1); cmd5.execute(); cmd6.execute(); cmd7.execute(); cmd8.execute(); // everything has failed in the test window so we should return false now Thread.sleep(100); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** Test that if the % of timeouts is higher than the threshold that the circuit trips. */ @Test public void testTripCircuitOnTimeoutsAboveThreshold() { String key = "cmd-E"; try { HystrixCommand<Boolean> cmd1 = new SuccessCommand(key, 60); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); // success with high latency cmd1.execute(); HystrixCommand<Boolean> cmd2 = new SuccessCommand(key, 1); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new TimeoutCommand(key); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new SuccessCommand(key, 1); cmd4.execute(); HystrixCommand<Boolean> cmd5 = new TimeoutCommand(key); cmd5.execute(); HystrixCommand<Boolean> cmd6 = new TimeoutCommand(key); cmd6.execute(); HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 1); cmd7.execute(); HystrixCommand<Boolean> cmd8 = new TimeoutCommand(key); cmd8.execute(); HystrixCommand<Boolean> cmd9 = new TimeoutCommand(key); cmd9.execute(); // this should trip the circuit as the error percentage is above the threshold Thread.sleep(100); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** * Test that on an open circuit that a single attempt will be allowed after a window of time to * see if issues are resolved. */ @Test public void testSingleTestOnOpenCircuitAfterTimeWindow() { String key = "cmd-F"; try { int sleepWindow = 200; HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); cmd1.execute(); HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new FailureCommand(key, 1); cmd4.execute(); // everything has failed in the test window so we should return false now Thread.sleep(100); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); // wait for sleepWindow to pass Thread.sleep(sleepWindow + 50); // we should now allow 1 request assertTrue(cb.allowRequest()); // but the circuit should still be open assertTrue(cb.isOpen()); // and further requests are still blocked assertFalse(cb.allowRequest()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
/** * Over a period of several 'windows' a single attempt will be made and fail and then finally * succeed and close the circuit. * * <p>Ensure the circuit is kept open through the entire testing period and that only the single * attempt in each window is made. */ @Test public void testMultipleTimeWindowRetriesBeforeClosingCircuit() { String key = "cmd-H"; try { int sleepWindow = 200; HystrixCommand<Boolean> cmd1 = new FailureCommand(key, 60); HystrixCircuitBreaker cb = cmd1.circuitBreaker; // this should start as allowing requests assertTrue(cb.allowRequest()); assertFalse(cb.isOpen()); cmd1.execute(); HystrixCommand<Boolean> cmd2 = new FailureCommand(key, 1); cmd2.execute(); HystrixCommand<Boolean> cmd3 = new FailureCommand(key, 1); cmd3.execute(); HystrixCommand<Boolean> cmd4 = new TimeoutCommand(key); cmd4.execute(); // everything has failed in the test window so we should return false now System.out.println("!!!! 1 4 failures, circuit will open on recalc"); Thread.sleep(100); assertFalse(cb.allowRequest()); assertTrue(cb.isOpen()); // wait for sleepWindow to pass System.out.println("!!!! 2 Sleep window starting where all commands fail-fast"); Thread.sleep(sleepWindow + 50); System.out.println("!!!! 3 Sleep window over, should allow singleTest()"); // but the circuit should still be open assertTrue(cb.isOpen()); // we should now allow 1 request, and upon failure, should not affect the circuit breaker, // which should remain open HystrixCommand<Boolean> cmd5 = new FailureCommand(key, 60); Observable<Boolean> asyncResult5 = cmd5.observe(); System.out.println("!!!! Kicked off the single-test"); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); System.out.println("!!!! Confirmed that no other requests go out during single-test"); asyncResult5.toBlocking().single(); System.out.println("!!!! SingleTest just completed"); // all requests should still be blocked, because the singleTest failed assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); // wait for sleepWindow to pass System.out.println("!!!! 2nd sleep window START"); Thread.sleep(sleepWindow + 50); System.out.println("!!!! 2nd sleep window over"); // we should now allow 1 request, and upon failure, should not affect the circuit breaker, // which should remain open HystrixCommand<Boolean> cmd6 = new FailureCommand(key, 60); Observable<Boolean> asyncResult6 = cmd6.observe(); System.out.println("2nd singleTest just kicked off"); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); System.out.println("confirmed that 2nd singletest only happened once"); asyncResult6.toBlocking().single(); System.out.println("2nd singleTest now over"); // all requests should still be blocked, because the singleTest failed assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); assertFalse(cb.allowRequest()); // wait for sleepWindow to pass Thread.sleep(sleepWindow + 50); // but the circuit should still be open assertTrue(cb.isOpen()); // we should now allow 1 request, and upon success, should cause the circuit to be closed HystrixCommand<Boolean> cmd7 = new SuccessCommand(key, 60); Observable<Boolean> asyncResult7 = cmd7.observe(); // and further requests are still blocked while the singleTest command is in flight assertFalse(cb.allowRequest()); asyncResult7.toBlocking().single(); // all requests should be open again assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); assertTrue(cb.allowRequest()); // and the circuit should be closed again assertFalse(cb.isOpen()); // and the circuit should be closed again assertFalse(cb.isOpen()); } catch (Exception e) { e.printStackTrace(); fail("Error occurred: " + e.getMessage()); } }
@Override public void run() { try { // command metrics for (HystrixCommandMetrics commandMetrics : HystrixCommandMetrics.getInstances()) { HystrixCommandKey key = commandMetrics.getCommandKey(); HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key); StringWriter jsonString = new StringWriter(); JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); // Informational and Status json.writeStartObject(); json.writeStringField(type.value, HystrixCommand.value); json.writeStringField(name.value, key.name()); json.writeStringField(group.value, commandMetrics.getCommandGroup().name()); json.writeNumberField(currentTime.value, (int) (System.currentTimeMillis() / 1000)); // circuit breaker json.writeBooleanField(isCircuitBreakerOpen.value, circuitBreaker.isOpen()); HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics.getHealthCounts(); json.writeNumberField(errorPercentage.value, healthCounts.getErrorPercentage()); json.writeNumberField(errorCount.value, healthCounts.getErrorCount()); json.writeNumberField(requestCount.value, healthCounts.getTotalRequests()); // rolling counters Gauge json.writeNumberField( rollingCountCollapsedRequests.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.COLLAPSED)); json.writeNumberField( rollingCountExceptionsThrown.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN)); json.writeNumberField( rollingCountFailure.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.FAILURE)); json.writeNumberField( rollingCountFallbackFailure.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE)); json.writeNumberField( rollingCountFallbackRejection.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION)); json.writeNumberField( rollingCountFallbackSuccess.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)); json.writeNumberField( rollingCountResponsesFromCache.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE)); json.writeNumberField( rollingCountSemaphoreRejected.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED)); json.writeNumberField( rollingCountShortCircuited.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED)); json.writeNumberField( rollingCountSuccess.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS)); json.writeNumberField( rollingCountThreadPoolRejected.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED)); json.writeNumberField( rollingCountTimeout.value, commandMetrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT)); json.writeNumberField( currentConcurrentExecutionCount.value, commandMetrics.getCurrentConcurrentExecutionCount()); // latency percentiles json.writeNumberField(latencyExecute_mean.value, commandMetrics.getExecutionTimeMean()); json.writeObjectFieldStart(latencyExecute.value); json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25)); json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50)); json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75)); json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90)); json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95)); json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99)); json.writeNumberField("99.5", commandMetrics.getExecutionTimePercentile(99.5)); json.writeNumberField("100", commandMetrics.getExecutionTimePercentile(100)); json.writeEndObject(); // json.writeNumberField(latencyTotal_mean.value, commandMetrics.getTotalTimeMean()); json.writeObjectFieldStart(latencyTotal.value); json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5)); json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); json.writeEndObject(); // property values for reporting what is actually seen by the command rather than what was // set somewhere HystrixCommandProperties commandProperties = commandMetrics.getProperties(); json.writeNumberField( propertyValue_circuitBreakerRequestVolumeThreshold.value, commandProperties.circuitBreakerRequestVolumeThreshold().get()); json.writeNumberField( propertyValue_circuitBreakerSleepWindowInMilliseconds.value, commandProperties.circuitBreakerSleepWindowInMilliseconds().get()); json.writeNumberField( propertyValue_circuitBreakerErrorThresholdPercentage.value, commandProperties.circuitBreakerErrorThresholdPercentage().get()); json.writeBooleanField( propertyValue_circuitBreakerForceOpen.value, commandProperties.circuitBreakerForceOpen().get()); json.writeBooleanField( propertyValue_circuitBreakerForceClosed.value, commandProperties.circuitBreakerForceClosed().get()); json.writeBooleanField( propertyValue_circuitBreakerEnabled.value, commandProperties.circuitBreakerEnabled().get()); json.writeStringField( propertyValue_executionIsolationStrategy.value, commandProperties.executionIsolationStrategy().get().name()); json.writeNumberField( propertyValue_executionIsolationThreadTimeoutInMilliseconds.value, commandProperties.executionIsolationThreadTimeoutInMilliseconds().get()); json.writeBooleanField( propertyValue_executionIsolationThreadInterruptOnTimeout.value, commandProperties.executionIsolationThreadInterruptOnTimeout().get()); json.writeStringField( propertyValue_executionIsolationThreadPoolKeyOverride.value, commandProperties.executionIsolationThreadPoolKeyOverride().get()); json.writeNumberField( propertyValue_executionIsolationSemaphoreMaxConcurrentRequests.value, commandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get()); json.writeNumberField( propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests.value, commandProperties.fallbackIsolationSemaphoreMaxConcurrentRequests().get()); /* * The following are commented out as these rarely change and are verbose for streaming for something people don't change. * We could perhaps allow a property or request argument to include these. */ // json.put("propertyValue_metricsRollingPercentileEnabled", // commandProperties.metricsRollingPercentileEnabled().get()); // json.put("propertyValue_metricsRollingPercentileBucketSize", // commandProperties.metricsRollingPercentileBucketSize().get()); // json.put("propertyValue_metricsRollingPercentileWindow", // commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); // json.put("propertyValue_metricsRollingPercentileWindowBuckets", // commandProperties.metricsRollingPercentileWindowBuckets().get()); // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", // commandProperties.metricsRollingStatisticalWindowBuckets().get()); json.writeNumberField( propertyValue_metricsRollingStatisticalWindowInMilliseconds.value, commandProperties.metricsRollingStatisticalWindowInMilliseconds().get()); json.writeBooleanField( propertyValue_requestCacheEnabled.value, commandProperties.requestCacheEnabled().get()); json.writeBooleanField( propertyValue_requestLogEnabled.value, commandProperties.requestLogEnabled().get()); json.writeNumberField(reportingHosts.value, 1); json.writeStringField(Key.ip.value, app_ip); json.writeEndObject(); json.close(); // System.out.println(ip + ":" + port + "||" + // jsonString.getBuffer().toString()); UDPClient.send( socketIp, socketPort, jsonString.getBuffer().toString().getBytes(), new byte[] {}); } // thread pool metrics for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics.getInstances()) { HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey(); StringWriter jsonString = new StringWriter(); JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); json.writeStartObject(); json.writeStringField(type.value, HystrixThreadPool.value); json.writeStringField(name.value, key.name()); json.writeNumberField(currentTime.value, System.currentTimeMillis()); // 101.3 80 154 json.writeNumberField( currentActiveCount.value, threadPoolMetrics.getCurrentActiveCount().intValue()); json.writeNumberField( currentCompletedTaskCount.value, threadPoolMetrics.getCurrentCompletedTaskCount().longValue()); json.writeNumberField( currentCorePoolSize.value, threadPoolMetrics.getCurrentCorePoolSize().intValue()); json.writeNumberField( currentLargestPoolSize.value, threadPoolMetrics.getCurrentLargestPoolSize().intValue()); json.writeNumberField( currentMaximumPoolSize.value, threadPoolMetrics.getCurrentMaximumPoolSize().intValue()); json.writeNumberField( currentPoolSize.value, threadPoolMetrics.getCurrentPoolSize().intValue()); json.writeNumberField( currentQueueSize.value, threadPoolMetrics.getCurrentQueueSize().intValue()); json.writeNumberField( currentTaskCount.value, threadPoolMetrics.getCurrentTaskCount().longValue()); json.writeNumberField( rollingCountThreadsExecuted.value, threadPoolMetrics.getRollingCountThreadsExecuted()); json.writeNumberField( rollingMaxActiveThreads.value, threadPoolMetrics.getRollingMaxActiveThreads()); json.writeNumberField( propertyValue_queueSizeRejectionThreshold.value, threadPoolMetrics.getProperties().queueSizeRejectionThreshold().get()); json.writeNumberField( propertyValue_metricsRollingStatisticalWindowInMilliseconds.value, threadPoolMetrics .getProperties() .metricsRollingStatisticalWindowInMilliseconds() .get()); json.writeNumberField( reportingHosts.value, 1); // this will get summed across all instances in a cluster json.writeStringField(Key.ip.value, app_ip); json.writeEndObject(); json.close(); String str = jsonString.getBuffer().toString(); byte[] ret = str.getBytes(); UDPClient.send(socketIp, socketPort, ret, new byte[] {}); } } catch (Exception e) { System.err.println("Failed to output metrics as JSON"); e.printStackTrace(); } }