Skip to content

Conversation

@zeitlinger
Copy link
Member

Fixes #1838

Summary

Addresses #1838 by verifying and documenting that client_java fully supports native histograms with custom buckets (NHCB, schema -53).

Background

According to the Prometheus Native Histograms specification, NHCB is handled by:

  1. Clients expose classic histograms with custom bucket boundaries
  2. Prometheus servers convert them to native histograms (schema -53) when configured with convert_classic_histograms_to_nhcb: true
  3. Custom bucket boundaries are preserved in the conversion

Changes

1. Comprehensive Test Suite ✅

  • File: prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CustomBucketsHistogramTest.java
  • Tests: 11 comprehensive tests (all passing)
  • Coverage:
    • Arbitrary custom bucket boundaries
    • Linear boundaries (equal-width buckets)
    • Exponential boundaries (for data spanning multiple orders of magnitude)
    • Classic-only and dual-mode histograms
    • Text and protobuf format serialization
    • Labeled histograms with custom buckets
    • Boundary edge cases and fine-grained precision

2. Documentation ✅

  • File: docs/content/getting-started/metric-types.md
  • Added:
    • Custom Bucket Boundaries section with examples for arbitrary, linear, and exponential boundaries
    • Native Histograms with Custom Buckets (NHCB) section explaining:
      • How NHCB works
      • Prometheus server configuration
      • When to use NHCB vs standard native histograms
      • Comparison table

3. Working Example ✅

  • New module: examples/example-custom-buckets/
  • Demonstrates: Three real-world use cases:
    • API latency with arbitrary custom boundaries (0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0 seconds)
    • Queue size with linear boundaries (10, 20, 30, ..., 100)
    • Response size with exponential boundaries (100, 1k, 10k, 100k, 1M, 10M bytes)
  • Includes:
    • Docker Compose setup with Prometheus (NHCB enabled) and Grafana
    • Pre-configured Grafana dashboard showing all three histogram types
    • Comprehensive README with build/run instructions and verification steps

4. Verification Report ✅

  • File: CUSTOM_BUCKETS_VERIFICATION.md
  • Documents: Detailed findings, test methodology, and verification results

Test Results

[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

All tests pass successfully, confirming that custom bucket support works correctly in all scenarios.

Key Findings

Custom bucket support is fully functional

  • The Java client correctly handles histograms with custom bucket boundaries
  • Dual-mode operation (classic + native) works seamlessly with custom buckets
  • Custom buckets are properly serialized in both text and protobuf formats
  • Prometheus servers can convert these to NHCB (schema -53) upon ingestion

How to Test

Run the tests:

./mvnw test -Dtest=CustomBucketsHistogramTest -pl prometheus-metrics-core

Run the example:

./mvnw package
cd examples/example-custom-buckets
docker-compose up

Then visit:

Documentation Links

… custom buckets (NHCB)

Implements issue #1838 by verifying and documenting that client_java fully
supports native histograms with custom buckets (NHCB, schema -53).

According to the Prometheus specification, NHCB is handled by exposing
classic histograms with custom bucket boundaries, which Prometheus servers
convert to native histograms (schema -53) when configured with
convert_classic_histograms_to_nhcb.

Changes:
- Add comprehensive test suite (11 tests) verifying custom bucket support
  for arbitrary, linear, and exponential boundaries
- Add documentation section on custom buckets and NHCB to metric-types.md
- Create complete working example with Docker Compose (Prometheus + Grafana)
- Add verification report documenting findings

Test coverage:
- Arbitrary custom boundaries
- Linear boundaries (equal-width buckets)
- Exponential boundaries
- Classic-only and dual-mode histograms
- Text and protobuf format serialization
- Labeled histograms and edge cases

All 11 tests pass successfully.

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
- Compress table columns to fit 100 char line limit
- Break long URL link across lines

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR verifies and documents that client_java supports native histograms with custom buckets (NHCB, schema -53), adds a concrete end‑to‑end example wired to Prometheus and Grafana, and updates contributor guidance around formatting and linting.

Changes:

  • Add a comprehensive CustomBucketsHistogramTest suite covering arbitrary, linear, exponential, labeled, classic-only, and dual-mode histograms with custom buckets, including text and protobuf serialization.
  • Introduce an example-custom-buckets module with a runnable Java app, Docker Compose setup (Prometheus with NHCB enabled, Grafana dashboard), and README showing NHCB usage and verification.
  • Extend metric-types.md with documentation for custom bucket APIs and NHCB usage, and update CLAUDE.md with stricter style and linting guidance (with one mismatch vs. actual mise task behavior).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CustomBucketsHistogramTest.java New targeted tests that exercise classic custom bucket configuration (arbitrary/linear/exponential/negative/fine-grained), labeled histograms, and dual classic+native behavior, including text and protobuf export.
examples/pom.xml Registers the new example-custom-buckets module in the examples aggregator so it builds with the rest of the project.
examples/example-custom-buckets/src/main/java/io/prometheus/metrics/examples/custombuckets/Main.java Example application wiring three histograms (arbitrary, linear, exponential custom buckets) with JVM metrics and an HTTP exporter on port 9400.
examples/example-custom-buckets/pom.xml Maven module definition and shade configuration for the example, mirroring the existing example-native-histogram module.
examples/example-custom-buckets/docker-compose/prometheus.yml Prometheus scrape config using protobuf (scrape_protocols: ["PrometheusProto"]), enabling convert_classic_histograms_to_nhcb and also scraping classic histograms for comparison.
examples/example-custom-buckets/docker-compose/grafana-datasources.yaml Sets up a Prometheus datasource in Grafana pointing at http://localhost:9090.
examples/example-custom-buckets/docker-compose/grafana-dashboards.yaml Provisions a Grafana dashboard file for the custom-buckets NHCB example.
examples/example-custom-buckets/docker-compose/grafana-dashboard-custom-buckets.json Pre-built Grafana dashboard panels showing p50/p95 quantiles for the three example histograms using PromQL histogram_quantile over the example metrics.
examples/example-custom-buckets/docker-compose.yaml Docker Compose stack wiring the example app (Java image), Prometheus (with native histograms enabled), and Grafana, all using host networking and mounted configs.
examples/example-custom-buckets/README.md Documentation for building, running, and validating the NHCB example, including Prometheus config snippet and guidance on observing quantiles and behavior in Prometheus and Grafana.
docs/content/getting-started/metric-types.md Adds “Custom Bucket Boundaries” (arbitrary/linear/exponential) and “Native Histograms with Custom Buckets (NHCB)” sections describing how to configure histograms and how Prometheus converts them when convert_classic_histograms_to_nhcb is enabled.
CLAUDE.md Tightens style and linting guidance (line length, code block languages, mise run lint:super-linter), but incorrectly states that mise run build runs all tests even though the build task in mise.toml skips tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Code formatting (Spotless with Google Java Format)
- Static analysis (Error Prone with NullAway)
- Checkstyle validation
- All tests pass
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description of mise run build here says it ensures that all tests pass, but the build task in mise.toml runs Maven with -DskipTests, so tests are not actually executed. Please either adjust this text to call out that tests are skipped, or point to a task/command (such as mise run test-all) that really runs the full test suite.

Suggested change
- All tests pass
- Build succeeds (tests are skipped; run `mise run test` or `mise run test-all` to execute tests)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Verify that client_java supports native histograms with custom buckets

2 participants