or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

base-sse-servlet.mdconfiguration-streaming.mdindex.mdlegacy-metrics-polling.mdmetrics-streaming.mdrequest-events-streaming.mdutilization-streaming.md

legacy-metrics-polling.mddocs/

0

# Legacy Metrics Polling (Deprecated)

1

2

Polling-based metrics collection system for Hystrix metrics. This functionality is deprecated since version 1.5.4 in favor of reactive stream-based approaches.

3

4

## Capabilities

5

6

### HystrixMetricsPoller (Deprecated)

7

8

Background poller that collects Hystrix metrics and outputs JSON strings to a listener interface.

9

10

```java { .api }

11

/**

12

* Polls Hystrix metrics and output JSON strings for each metric to a MetricsPollerListener.

13

* Polling can be stopped/started. Use shutdown() to permanently shutdown the poller.

14

*

15

* @deprecated Since 1.5.4 - prefer HystrixDashboardStream

16

*/

17

@Deprecated

18

public class HystrixMetricsPoller {

19

20

/**

21

* Allocate resources to begin polling

22

* @param listener Callback interface for receiving metric JSON

23

* @param delay Delay between polling cycles in milliseconds

24

*/

25

public HystrixMetricsPoller(MetricsAsJsonPollerListener listener, int delay);

26

27

/**

28

* Start polling - can be called multiple times safely

29

*/

30

public synchronized void start();

31

32

/**

33

* Pause polling - can be restarted with start()

34

*/

35

public synchronized void pause();

36

37

/**

38

* Stop polling and shutdown executor - instance cannot be reused

39

*/

40

public synchronized void shutdown();

41

42

/**

43

* Check if poller is currently running

44

* @return true if poller is active

45

*/

46

public boolean isRunning();

47

48

/**

49

* Listener interface for receiving metric JSON strings

50

*/

51

public static interface MetricsAsJsonPollerListener {

52

/**

53

* Handle JSON metric data

54

* @param json JSON string containing metric data

55

*/

56

public void handleJsonMetric(String json);

57

}

58

}

59

```

60

61

### MetricsPollerThreadFactory

62

63

Custom thread factory for creating poller threads.

64

65

```java { .api }

66

/**

67

* Thread factory for creating named daemon threads for metrics polling

68

*/

69

private static class MetricsPollerThreadFactory implements ThreadFactory {

70

private static final String MetricsThreadName = "HystrixMetricPoller";

71

72

/**

73

* Create new daemon thread with specific name for metrics polling

74

* @param r Runnable to execute

75

* @return Configured thread

76

*/

77

public Thread newThread(Runnable r);

78

}

79

```

80

81

**Usage Examples:**

82

83

```java

84

// Basic metrics polling setup

85

HystrixMetricsPoller.MetricsAsJsonPollerListener listener = new HystrixMetricsPoller.MetricsAsJsonPollerListener() {

86

@Override

87

public void handleJsonMetric(String json) {

88

System.out.println("Metric: " + json);

89

// Send to monitoring system, log, etc.

90

}

91

};

92

93

HystrixMetricsPoller poller = new HystrixMetricsPoller(listener, 1000); // 1 second interval

94

poller.start();

95

96

// Later - pause polling temporarily

97

poller.pause();

98

99

// Resume polling

100

poller.start();

101

102

// Permanently shutdown

103

poller.shutdown();

104

105

// Custom metrics processing

106

HystrixMetricsPoller poller = new HystrixMetricsPoller(json -> {

107

// Parse JSON and extract specific metrics

108

ObjectMapper mapper = new ObjectMapper();

109

JsonNode metrics = mapper.readTree(json);

110

111

if ("HystrixCommand".equals(metrics.get("type").asText())) {

112

String commandName = metrics.get("name").asText();

113

int errorCount = metrics.get("errorCount").asInt();

114

115

if (errorCount > 0) {

116

alertingService.sendAlert("Command errors detected", commandName);

117

}

118

}

119

}, 5000);

120

```

121

122

## Metrics Collection Details

123

124

### Data Collection Process

125

126

The poller collects three types of metrics in each polling cycle:

127

128

1. **HystrixCommand Metrics**: For each command instance

129

2. **HystrixThreadPool Metrics**: For thread pools with executed commands

130

3. **HystrixCollapser Metrics**: For each collapser instance

131

132

### Threading Model

133

134

- **Single Background Thread**: One daemon thread per poller instance

135

- **Scheduled Execution**: Uses ScheduledThreadPoolExecutor with fixed delay

136

- **Platform Specific**: Uses App Engine compatible thread factory when detected

137

- **Automatic Cleanup**: Finalizer guardian prevents thread leaks

138

139

### Version Compatibility Handling

140

141

The poller includes special handling for version mismatches:

142

143

```java { .api }

144

/**

145

* Safely write number field with version mismatch protection

146

* If HystrixEventType doesn't exist in current version, writes 0

147

* @param json JsonGenerator to write to

148

* @param name Field name to write

149

* @param metricGenerator Function that generates the metric value

150

* @throws IOException if JSON writing fails

151

*/

152

private void safelyWriteNumberField(JsonGenerator json, String name, Func0<Long> metricGenerator) throws IOException;

153

```

154

155

## JSON Output Format

156

157

### Command Metrics

158

159

```json

160

{

161

"type": "HystrixCommand",

162

"name": "GetUser",

163

"group": "UserService",

164

"currentTime": 1355239617628,

165

"isCircuitBreakerOpen": false,

166

"errorPercentage": 0,

167

"errorCount": 0,

168

"requestCount": 121,

169

"rollingCountSuccess": 121,

170

"rollingCountFailure": 0,

171

"rollingCountTimeout": 0,

172

"rollingCountShortCircuited": 0,

173

"rollingCountThreadPoolRejected": 0,

174

"rollingCountSemaphoreRejected": 0,

175

"rollingCountFallbackSuccess": 0,

176

"rollingCountFallbackFailure": 0,

177

"rollingCountFallbackRejection": 0,

178

"rollingCountExceptionsThrown": 0,

179

"rollingCountResponsesFromCache": 69,

180

"rollingCountCollapsedRequests": 0,

181

"currentConcurrentExecutionCount": 0,

182

"rollingMaxConcurrentExecutionCount": 3,

183

"latencyExecute_mean": 13,

184

"latencyExecute": {

185

"0": 3, "25": 6, "50": 8, "75": 14, "90": 26, "95": 37, "99": 75, "99.5": 92, "100": 252

186

},

187

"latencyTotal_mean": 15,

188

"latencyTotal": {

189

"0": 3, "25": 7, "50": 10, "75": 18, "90": 32, "95": 43, "99": 88, "99.5": 160, "100": 253

190

},

191

"propertyValue_circuitBreakerRequestVolumeThreshold": 20,

192

"propertyValue_circuitBreakerSleepWindowInMilliseconds": 5000,

193

"propertyValue_executionIsolationStrategy": "THREAD",

194

"propertyValue_executionIsolationThreadTimeoutInMilliseconds": 800,

195

"propertyValue_requestCacheEnabled": true,

196

"propertyValue_requestLogEnabled": true,

197

"reportingHosts": 1,

198

"threadPool": "UserService"

199

}

200

```

201

202

### Thread Pool Metrics

203

204

```json

205

{

206

"type": "HystrixThreadPool",

207

"name": "UserService",

208

"currentTime": 1355239617628,

209

"currentActiveCount": 0,

210

"currentCompletedTaskCount": 4459519,

211

"currentCorePoolSize": 30,

212

"currentLargestPoolSize": 30,

213

"currentMaximumPoolSize": 30,

214

"currentPoolSize": 30,

215

"currentQueueSize": 0,

216

"currentTaskCount": 4459519,

217

"rollingMaxActiveThreads": 13,

218

"rollingCountThreadsExecuted": 919,

219

"rollingCountCommandRejections": 0,

220

"propertyValue_queueSizeRejectionThreshold": 30,

221

"propertyValue_metricsRollingStatisticalWindowInMilliseconds": 30000,

222

"reportingHosts": 3

223

}

224

```

225

226

### Collapser Metrics

227

228

```json

229

{

230

"type": "HystrixCollapser",

231

"name": "UserDataCollapser",

232

"currentTime": 1355239617628,

233

"rollingCountRequestsBatched": 150,

234

"rollingCountBatches": 15,

235

"rollingCountResponsesFromCache": 25,

236

"batchSize_mean": 10,

237

"batchSize": {

238

"25": 8, "50": 10, "75": 12, "90": 15, "95": 18, "99": 25, "99.5": 28, "100": 30

239

},

240

"propertyValue_requestCacheEnabled": true,

241

"propertyValue_maxRequestsInBatch": 100,

242

"propertyValue_timerDelayInMilliseconds": 10,

243

"reportingHosts": 1

244

}

245

```

246

247

## Error Handling

248

249

### Exception Management

250

251

```java

252

// Polling cycle error handling

253

try {

254

// Collect metrics for commands, thread pools, collapsers

255

} catch (Exception e) {

256

logger.warn("Failed to output metrics as JSON", e);

257

pause(); // Stop polling on error

258

return;

259

}

260

```

261

262

### Resource Cleanup

263

264

```java

265

// Finalizer guardian prevents resource leaks

266

private final Object finalizerGuardian = new Object() {

267

protected void finalize() throws Throwable {

268

if (!executor.isShutdown()) {

269

logger.warn("HystrixMetricsPoller was not shutdown. Caught in Finalize Guardian and shutting down.");

270

shutdown();

271

}

272

}

273

};

274

```

275

276

## Migration to Modern API

277

278

### From Poller to Stream

279

280

```java

281

// Old approach (deprecated)

282

HystrixMetricsPoller poller = new HystrixMetricsPoller(json -> {

283

// Process JSON

284

}, 1000);

285

poller.start();

286

287

// New approach (recommended)

288

HystrixDashboardStream.getInstance()

289

.observe()

290

.flatMap(dashboardData ->

291

Observable.from(SerialHystrixDashboardData.toMultipleJsonStrings(dashboardData))

292

)

293

.subscribe(json -> {

294

// Process JSON

295

});

296

```

297

298

### Benefits of Stream-Based Approach

299

300

- **Better Resource Management**: No background threads or executors to manage

301

- **Reactive Programming**: Built on RxJava for composable, non-blocking operations

302

- **Efficient Sharing**: Multiple consumers can share the same stream

303

- **Consistent API**: Same pattern used across all Hystrix streaming components

304

- **Better Error Handling**: Reactive error propagation and recovery