|
| 1 | +# Native Histograms with Custom Buckets - Verification Report |
| 2 | + |
| 3 | +## Issue #1838: Verify that client_java supports native histograms with custom buckets |
| 4 | + |
| 5 | +### Summary |
| 6 | + |
| 7 | +This report documents the verification that the Prometheus Java client library properly supports native histograms with custom bucket configurations (NHCB - Native Histograms with Custom Buckets). |
| 8 | + |
| 9 | +### Background |
| 10 | + |
| 11 | +According to the [Prometheus Native Histograms specification](https://prometheus.io/docs/specs/native_histograms/), native histograms with custom buckets (schema -53) are a feature that allows representing classic histograms as native histograms with explicit bucket boundaries. |
| 12 | + |
| 13 | +**Key findings from the specification:** |
| 14 | +- Schema -53 is used for custom bucket boundaries |
| 15 | +- There is currently no dedicated protobuf field for custom bucket boundaries |
| 16 | +- Custom-bucket histograms are exposed as **classic histograms** with custom boundaries |
| 17 | +- Prometheus servers convert these to NHCB upon ingestion when configured with `convert_classic_histograms_to_nhcb` |
| 18 | + |
| 19 | +### Verification Approach |
| 20 | + |
| 21 | +The Java client library already supports custom bucket configurations through the `classicUpperBounds()`, `classicLinearUpperBounds()`, and `classicExponentialUpperBounds()` builder methods. These methods allow users to define custom bucket boundaries for histograms. |
| 22 | + |
| 23 | +Since NHCB is handled by Prometheus servers during ingestion (not by client libraries), our verification focuses on ensuring that: |
| 24 | + |
| 25 | +1. Histograms with custom bucket boundaries can be created |
| 26 | +2. Custom buckets are correctly exposed in both text and protobuf formats |
| 27 | +3. Both classic-only and dual (classic+native) histograms work with custom buckets |
| 28 | +4. Various custom bucket configurations work correctly |
| 29 | + |
| 30 | +### Test Implementation |
| 31 | + |
| 32 | +Created comprehensive test suite: `CustomBucketsHistogramTest.java` |
| 33 | + |
| 34 | +The test suite includes 11 tests covering: |
| 35 | + |
| 36 | +#### 1. **Custom Buckets with Arbitrary Boundaries** (`testCustomBucketsWithArbitraryBoundaries`) |
| 37 | +- Tests histogram with arbitrary custom bucket boundaries |
| 38 | +- Verifies observations are distributed correctly across buckets |
| 39 | +- Validates count and sum calculations |
| 40 | + |
| 41 | +#### 2. **Custom Buckets with Linear Boundaries** (`testCustomBucketsWithLinearBoundaries`) |
| 42 | +- Tests histogram with linear custom bucket boundaries (equal-width buckets) |
| 43 | +- Use case: Queue size monitoring with fixed intervals |
| 44 | + |
| 45 | +#### 3. **Custom Buckets with Exponential Boundaries** (`testCustomBucketsWithExponentialBoundaries`) |
| 46 | +- Tests histogram with exponential custom bucket boundaries |
| 47 | +- Use case: Metrics spanning multiple orders of magnitude (e.g., response sizes) |
| 48 | + |
| 49 | +#### 4. **Classic-Only Histogram with Custom Buckets** (`testCustomBucketsClassicOnlyHistogram`) |
| 50 | +- Verifies custom buckets work when using `.classicOnly()` |
| 51 | +- Confirms no native histogram representation is maintained |
| 52 | + |
| 53 | +#### 5. **Dual-Mode Histogram with Custom Buckets** (`testCustomBucketsDualModeHistogram`) |
| 54 | +- Tests the default mode (both classic and native representations) |
| 55 | +- Verifies custom classic buckets coexist with native histogram representation |
| 56 | +- **This is the most relevant test for NHCB support** |
| 57 | + |
| 58 | +#### 6. **Text Format Output** (`testCustomBucketsTextFormatOutput`) |
| 59 | +- Verifies custom buckets are correctly serialized in Prometheus text format |
| 60 | +- Validates bucket labels (le) and counts |
| 61 | + |
| 62 | +#### 7. **Protobuf Format Output** (`testCustomBucketsProtobufFormatOutput`) |
| 63 | +- Verifies custom buckets are correctly serialized in Prometheus protobuf format |
| 64 | +- Validates bucket upper bounds and cumulative counts |
| 65 | +- Confirms native histogram fields are present (for dual-mode) |
| 66 | + |
| 67 | +#### 8. **Custom Buckets with Negative Values** (`testCustomBucketsWithNegativeValues`) |
| 68 | +- Tests custom buckets with negative boundary values |
| 69 | +- Use case: Temperature or other metrics with negative ranges |
| 70 | + |
| 71 | +#### 9. **Custom Buckets with Labels** (`testCustomBucketsWithLabels`) |
| 72 | +- Verifies custom buckets work correctly with labeled histograms |
| 73 | +- Tests multiple label combinations |
| 74 | + |
| 75 | +#### 10. **Boundary Edge Cases** (`testCustomBucketsBoundaryEdgeCases`) |
| 76 | +- Tests observations exactly on bucket boundaries |
| 77 | +- Verifies buckets are inclusive of their upper bound |
| 78 | + |
| 79 | +#### 11. **Fine-Grained Custom Buckets** (`testCustomBucketsFineBoundaries`) |
| 80 | +- Tests with very precise custom bucket boundaries |
| 81 | +- Use case: High-precision measurements |
| 82 | + |
| 83 | +### Test Results |
| 84 | + |
| 85 | +All 11 tests pass successfully: |
| 86 | + |
| 87 | +``` |
| 88 | +[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0 |
| 89 | +[INFO] BUILD SUCCESS |
| 90 | +``` |
| 91 | + |
| 92 | +### Key Findings |
| 93 | + |
| 94 | +1. **Custom bucket support is fully functional**: The Java client library correctly handles histograms with custom bucket boundaries. |
| 95 | + |
| 96 | +2. **Dual-mode operation**: By default, histograms maintain both classic (with custom buckets) and native representations, which is ideal for NHCB support. |
| 97 | + |
| 98 | +3. **Correct serialization**: Custom buckets are properly serialized in both: |
| 99 | + - Text format (with `le` labels) |
| 100 | + - Protobuf format (with bucket upper bounds and cumulative counts) |
| 101 | + |
| 102 | +4. **Native histogram fields present**: When using dual-mode (default), the protobuf output includes native histogram fields (schema, zero_count, etc.) alongside the classic buckets. |
| 103 | + |
| 104 | +5. **Flexible bucket configurations**: The library supports: |
| 105 | + - Arbitrary custom boundaries |
| 106 | + - Linear boundaries (equal-width) |
| 107 | + - Exponential boundaries |
| 108 | + - Negative values |
| 109 | + - Very fine-grained precision |
| 110 | + |
| 111 | +### Conclusion |
| 112 | + |
| 113 | +**The Prometheus Java client library (client_java) fully supports native histograms with custom buckets.** |
| 114 | + |
| 115 | +The library correctly: |
| 116 | +- Allows users to define custom bucket boundaries |
| 117 | +- Maintains both classic and native histogram representations by default |
| 118 | +- Exposes custom buckets in the classic histogram format |
| 119 | +- Serializes correctly in both text and protobuf formats |
| 120 | + |
| 121 | +Prometheus servers can convert these histograms to NHCB (schema -53) upon ingestion when configured with the `convert_classic_histograms_to_nhcb` option. |
| 122 | + |
| 123 | +### Recommendations |
| 124 | + |
| 125 | +1. **Documentation**: Consider documenting the NHCB support in the user-facing documentation, explaining that: |
| 126 | + - Custom buckets are supported via the existing `classicUpperBounds()` API |
| 127 | + - Prometheus servers handle the conversion to NHCB (schema -53) |
| 128 | + - The default dual-mode is recommended for NHCB compatibility |
| 129 | + |
| 130 | +2. **Example**: Consider adding an example demonstrating custom bucket usage for NHCB scenarios. |
| 131 | + |
| 132 | +3. **Close issue #1838**: This verification confirms that custom bucket support is working correctly. |
| 133 | + |
| 134 | +### Test File Location |
| 135 | + |
| 136 | +- `prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CustomBucketsHistogramTest.java` |
| 137 | + |
| 138 | +### References |
| 139 | + |
| 140 | +- [Prometheus Native Histograms Specification](https://prometheus.io/docs/specs/native_histograms/) |
| 141 | +- [GitHub Issue #1838](https://github.com/prometheus/client_java/issues/1838) |
| 142 | +- [Prometheus client_model Repository](https://github.com/prometheus/client_model) |
0 commit comments