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