0
# Metrics JSON
1
2
Jackson JSON serialization support for Dropwizard Metrics library. This package provides Jackson modules that serialize various metrics objects (gauges, counters, histograms, meters, timers) and health check results to JSON format, enabling applications to easily export metrics data for monitoring dashboards, APIs, or storage systems.
3
4
## Package Information
5
6
- **Package Name**: metrics-json
7
- **Package Type**: Maven
8
- **Group ID**: io.dropwizard.metrics
9
- **Artifact ID**: metrics-json
10
- **Language**: Java
11
- **Installation**: Add dependency to your Maven project
12
13
```xml
14
<dependency>
15
<groupId>io.dropwizard.metrics</groupId>
16
<artifactId>metrics-json</artifactId>
17
<version>4.2.33</version>
18
</dependency>
19
```
20
21
## Core Imports
22
23
```java
24
import com.codahale.metrics.json.MetricsModule;
25
import com.codahale.metrics.json.HealthCheckModule;
26
import com.fasterxml.jackson.databind.ObjectMapper;
27
import com.codahale.metrics.MetricRegistry;
28
import com.codahale.metrics.Counter;
29
import com.codahale.metrics.Gauge;
30
import com.codahale.metrics.MetricFilter;
31
import java.util.concurrent.TimeUnit;
32
```
33
34
## Basic Usage
35
36
```java
37
import com.codahale.metrics.json.MetricsModule;
38
import com.codahale.metrics.json.HealthCheckModule;
39
import com.fasterxml.jackson.databind.ObjectMapper;
40
import com.codahale.metrics.MetricRegistry;
41
import com.codahale.metrics.Counter;
42
import com.codahale.metrics.Gauge;
43
import java.util.concurrent.TimeUnit;
44
45
// Configure ObjectMapper with metrics serialization
46
ObjectMapper mapper = new ObjectMapper()
47
.registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, false))
48
.registerModule(new HealthCheckModule());
49
50
// Serialize a MetricRegistry to JSON
51
MetricRegistry registry = new MetricRegistry();
52
Counter counter = registry.counter("requests");
53
counter.inc();
54
55
String json = mapper.writeValueAsString(registry);
56
// Output: {"version":"4.0.0","gauges":{},"counters":{"requests":{"count":1}},"histograms":{},"meters":{},"timers":{}}
57
58
// Serialize individual metrics
59
Gauge<Integer> gauge = () -> 42;
60
String gaugeJson = mapper.writeValueAsString(gauge);
61
// Output: {"value":42}
62
```
63
64
## Dependencies
65
66
Required dependencies:
67
- `com.fasterxml.jackson.core:jackson-core` (2.12.7)
68
- `com.fasterxml.jackson.core:jackson-databind` (2.12.7.2)
69
- `io.dropwizard.metrics:metrics-core` (4.2.33)
70
71
Optional dependencies:
72
- `io.dropwizard.metrics:metrics-healthchecks` (4.2.33) - Required for HealthCheckModule
73
74
## Capabilities
75
76
### Metrics JSON Serialization
77
78
Provides Jackson module for serializing Dropwizard Metrics objects to JSON format with configurable time units and filtering.
79
80
```java { .api }
81
/**
82
* Jackson module for serializing Dropwizard Metrics objects to JSON
83
*/
84
public class MetricsModule extends Module {
85
/** Module version used for Jackson registration */
86
static final Version VERSION = new Version(4, 0, 0, "", "io.dropwizard.metrics", "metrics-json");
87
/**
88
* Creates a MetricsModule with specified time units and sample visibility
89
* @param rateUnit Time unit for rate calculations (e.g., TimeUnit.SECONDS)
90
* @param durationUnit Time unit for duration measurements (e.g., TimeUnit.MILLISECONDS)
91
* @param showSamples Whether to include raw sample values in histogram/timer serialization
92
*/
93
public MetricsModule(TimeUnit rateUnit, TimeUnit durationUnit, boolean showSamples);
94
95
/**
96
* Creates a MetricsModule with time units, sample visibility, and metric filtering
97
* @param rateUnit Time unit for rate calculations
98
* @param durationUnit Time unit for duration measurements
99
* @param showSamples Whether to include raw sample values in serialization
100
* @param filter Filter for selecting which metrics to serialize
101
*/
102
public MetricsModule(TimeUnit rateUnit, TimeUnit durationUnit, boolean showSamples, MetricFilter filter);
103
104
/**
105
* Returns the module name for Jackson registration
106
* @return "metrics"
107
*/
108
public String getModuleName();
109
110
/**
111
* Returns the module version
112
* @return Version object (4.0.0)
113
*/
114
public Version version();
115
116
/**
117
* Configures the Jackson module with serializers for all metric types
118
* @param context Jackson setup context
119
*/
120
public void setupModule(SetupContext context);
121
}
122
```
123
124
**Supported Metric Types:**
125
126
The module provides JSON serialization for all Dropwizard Metrics types:
127
128
- **Gauge**: Serializes gauge values, handles exceptions gracefully
129
- **Counter**: Serializes counter count
130
- **Histogram**: Serializes count, min/max/mean, percentiles, optionally sample values, standard deviation
131
- **Meter**: Serializes count, rates (1min, 5min, 15min, mean), rate units
132
- **Timer**: Serializes count, duration statistics, rate statistics, units for both duration and rate
133
- **MetricRegistry**: Serializes entire registry with version and grouped metrics by type
134
135
**Configuration Options:**
136
137
```java
138
// Basic configuration with time units
139
MetricsModule module = new MetricsModule(
140
TimeUnit.SECONDS, // Rate unit - affects meter/timer rate calculations
141
TimeUnit.MILLISECONDS, // Duration unit - affects timer duration values
142
false // showSamples - whether to include raw sample data
143
);
144
145
// Advanced configuration with filtering
146
MetricsModule filteredModule = new MetricsModule(
147
TimeUnit.SECONDS,
148
TimeUnit.MILLISECONDS,
149
true, // Include sample values
150
MetricFilter.contains("api") // Only serialize metrics with "api" in name
151
);
152
```
153
154
### Health Check JSON Serialization
155
156
Provides Jackson module for serializing health check results with complete error information and metadata.
157
158
```java { .api }
159
/**
160
* Jackson module for serializing health check results to JSON
161
*/
162
public class HealthCheckModule extends Module {
163
/**
164
* Creates a new HealthCheckModule with default configuration
165
*/
166
public HealthCheckModule();
167
168
/**
169
* Returns the module name for Jackson registration
170
* @return "healthchecks"
171
*/
172
public String getModuleName();
173
174
/**
175
* Returns the module version (same as MetricsModule.VERSION)
176
* @return Version object (4.0.0)
177
*/
178
public Version version();
179
180
/**
181
* Configures the Jackson module with health check result serializer
182
* @param context Jackson setup context
183
*/
184
public void setupModule(SetupContext context);
185
}
186
```
187
188
**Serialized Components:**
189
190
The module serializes `HealthCheck.Result` objects with complete information:
191
192
- **healthy**: Boolean status of the health check
193
- **message**: Optional descriptive message
194
- **error**: Complete exception details including type, message, stack trace, and nested causes
195
- **duration**: Duration of health check execution in milliseconds
196
- **timestamp**: ISO timestamp of when the check was performed
197
- **custom details**: Any custom key-value pairs added to the result
198
199
**Usage Example:**
200
201
```java
202
import com.codahale.metrics.health.HealthCheck;
203
import com.codahale.metrics.json.HealthCheckModule;
204
205
// Configure ObjectMapper
206
ObjectMapper mapper = new ObjectMapper()
207
.registerModule(new HealthCheckModule());
208
209
// Serialize health check result
210
HealthCheck.Result result = HealthCheck.Result.healthy("All systems operational");
211
String json = mapper.writeValueAsString(result);
212
// Output: {"healthy":true,"message":"All systems operational","duration":5,"timestamp":"2023-10-15T10:30:00Z"}
213
214
// Serialize failed health check with error
215
HealthCheck.Result failedResult = HealthCheck.Result.unhealthy("Database connection failed",
216
new SQLException("Connection timeout"));
217
String failedJson = mapper.writeValueAsString(failedResult);
218
// Output includes full error details with stack trace
219
```
220
221
## JSON Output Formats
222
223
### Gauge JSON Format
224
```json
225
{
226
"value": 42
227
}
228
```
229
230
On exception:
231
```json
232
{
233
"error": "java.lang.RuntimeException: Gauge calculation failed"
234
}
235
```
236
237
### Counter JSON Format
238
```json
239
{
240
"count": 1337
241
}
242
```
243
244
### Histogram JSON Format
245
```json
246
{
247
"count": 1000,
248
"max": 95.0,
249
"mean": 45.2,
250
"min": 1.0,
251
"p50": 44.0,
252
"p75": 67.5,
253
"p95": 89.2,
254
"p98": 92.1,
255
"p99": 94.3,
256
"p999": 95.0,
257
"stddev": 15.8,
258
"values": [1.0, 2.0, 3.0]
259
}
260
```
261
262
Note: `values` array is only included when `showSamples=true`
263
264
### Meter JSON Format
265
```json
266
{
267
"count": 5000,
268
"m15_rate": 12.5,
269
"m1_rate": 15.2,
270
"m5_rate": 13.8,
271
"mean_rate": 14.1,
272
"units": "events/second"
273
}
274
```
275
276
### Timer JSON Format
277
```json
278
{
279
"count": 2500,
280
"max": 250.5,
281
"mean": 45.2,
282
"min": 0.5,
283
"p50": 42.0,
284
"p75": 65.8,
285
"p95": 120.4,
286
"p98": 180.2,
287
"p99": 220.8,
288
"p999": 245.1,
289
"stddev": 25.4,
290
"values": [0.5, 1.2, 2.8],
291
"m15_rate": 8.2,
292
"m1_rate": 10.1,
293
"m5_rate": 9.5,
294
"mean_rate": 8.8,
295
"duration_units": "milliseconds",
296
"rate_units": "calls/second"
297
}
298
```
299
300
Note: `values` array is only included when `showSamples=true`. All duration values (including individual values in the array) are scaled by the configured duration unit using a conversion factor of `1.0 / durationUnit.toNanos(1)`
301
302
### MetricRegistry JSON Format
303
```json
304
{
305
"version": "4.0.0",
306
"gauges": {
307
"jvm.memory.heap": {"value": 1234567890}
308
},
309
"counters": {
310
"requests.total": {"count": 12345}
311
},
312
"histograms": {
313
"response.size": {"count": 1000, "max": 95.0, "mean": 45.2, "min": 1.0, "p50": 44.0, "p75": 67.5, "p95": 89.2, "p98": 92.1, "p99": 94.3, "p999": 95.0, "stddev": 15.8}
314
},
315
"meters": {
316
"requests.rate": {"count": 5000, "m15_rate": 12.5, "m1_rate": 15.2, "m5_rate": 13.8, "mean_rate": 14.1, "units": "events/second"}
317
},
318
"timers": {
319
"requests.duration": {"count": 2500, "max": 250.5, "mean": 45.2, "min": 0.5, "p50": 42.0, "p75": 65.8, "p95": 120.4, "p98": 180.2, "p99": 220.8, "p999": 245.1, "stddev": 25.4, "m15_rate": 8.2, "m1_rate": 10.1, "m5_rate": 9.5, "mean_rate": 8.8, "duration_units": "milliseconds", "rate_units": "calls/second"}
320
}
321
}
322
```
323
324
### HealthCheck.Result JSON Format
325
```json
326
{
327
"healthy": true,
328
"message": "Database connection is healthy",
329
"duration": 15,
330
"timestamp": "2023-10-15T10:30:00Z",
331
"connection_pool_size": 10,
332
"active_connections": 3
333
}
334
```
335
336
With error:
337
```json
338
{
339
"healthy": false,
340
"message": "Database connection failed",
341
"error": {
342
"type": "java.sql.SQLException",
343
"message": "Connection timeout after 30 seconds",
344
"stack": [
345
"java.sql.DriverManager.getConnection(DriverManager.java:681)",
346
"com.example.DatabaseHealthCheck.check(DatabaseHealthCheck.java:25)"
347
],
348
"cause": {
349
"type": "java.net.SocketTimeoutException",
350
"message": "Read timeout",
351
"stack": ["java.net.SocketInputStream.socketRead0(Native Method)"]
352
}
353
},
354
"duration": 30000,
355
"timestamp": "2023-10-15T10:30:00Z"
356
}
357
```
358
359
## Types
360
361
```java { .api }
362
import java.util.concurrent.TimeUnit;
363
import com.codahale.metrics.MetricFilter;
364
import com.codahale.metrics.Metric;
365
import com.fasterxml.jackson.core.Version;
366
import com.fasterxml.jackson.databind.Module;
367
368
/**
369
* Jackson Module base class
370
*/
371
public abstract class Module {
372
public abstract String getModuleName();
373
public abstract Version version();
374
public abstract void setupModule(SetupContext context);
375
376
/**
377
* Setup context provided by Jackson during module registration
378
*/
379
public static interface SetupContext {
380
/** Add serializers for specific types */
381
void addSerializers(SimpleSerializers serializers);
382
/** Add deserializers for specific types */
383
void addDeserializers(SimpleDeserializers deserializers);
384
/** Add key serializers */
385
void addKeySerializers(SimpleKeySerializers keySerializers);
386
/** Add key deserializers */
387
void addKeyDeserializers(SimpleKeyDeserializers keyDeserializers);
388
/** Add abstract type resolvers */
389
void addAbstractTypeResolver(AbstractTypeResolver resolver);
390
/** Add type modifier */
391
void addTypeModifier(TypeModifier modifier);
392
/** Add value instantiators */
393
void addValueInstantiators(SimpleValueInstantiators instantiators);
394
/** Set bean serializer modifier */
395
void addBeanSerializerModifier(BeanSerializerModifier modifier);
396
/** Set bean deserializer modifier */
397
void addBeanDeserializerModifier(BeanDeserializerModifier modifier);
398
}
399
}
400
401
/**
402
* Predefined metric filters for selecting which metrics to serialize
403
*/
404
public interface MetricFilter {
405
/** Filter that accepts all metrics */
406
MetricFilter ALL = (name, metric) -> true;
407
408
/** Create filter that only accepts metrics whose names contain the given string */
409
static MetricFilter contains(String substring);
410
411
/** Determine if a metric should be included */
412
boolean matches(String name, Metric metric);
413
}
414
415
/**
416
* Base interface for all metrics
417
*/
418
public interface Metric {
419
// Marker interface for all metric types
420
}
421
422
/**
423
* Time units supported for rate and duration configuration
424
*/
425
public enum TimeUnit {
426
NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS;
427
428
/** Convert to seconds */
429
double toSeconds(long duration);
430
/** Convert to nanoseconds */
431
long toNanos(long duration);
432
}
433
```
434
435
## Error Handling
436
437
The modules handle errors gracefully:
438
439
- **Gauge Serialization**: Runtime exceptions during gauge value retrieval are caught and serialized as error objects with the exception string
440
- **HealthCheck Error Serialization**: Complete exception details are included with full stack traces and nested cause chains
441
- **Null Value Handling**: All serializers properly handle null values and missing optional fields
442
- **Type Safety**: Jackson's type system ensures proper serialization of all supported metric types