This file provides guidance to AI coding agents when working with code in this repository.
This project uses Maven with mise for task automation.
The Maven wrapper (./mvnw) is used for all builds.
# Full CI build (clean + install + all checks)
mise run ci
# Quick compile without tests or checks (fastest)
mise run compile
# Run unit tests only (skips formatting/coverage/checkstyle)
mise run test
# Run all tests including integration tests
mise run test-all
# Format code with Google Java Format
mise run format
# Run a single test class
./mvnw test -Dtest=CounterTest \
-Dspotless.check.skip=true \
-Dcoverage.skip=true -Dcheckstyle.skip=true
# Run a single test method
./mvnw test -Dtest=CounterTest#testIncrement \
-Dspotless.check.skip=true \
-Dcoverage.skip=true -Dcheckstyle.skip=true
# Run tests in a specific module
./mvnw test -pl prometheus-metrics-core \
-Dspotless.check.skip=true \
-Dcoverage.skip=true -Dcheckstyle.skip=true
# Regenerate protobuf classes (after protobuf dep update)
mise run generateThe library follows a layered architecture where metrics flow from core types through a registry to exporters:
prometheus-metrics-core (user-facing API)
│
▼ collect()
prometheus-metrics-model (immutable snapshots)
│
▼
prometheus-metrics-exposition-formats
│
▼
Exporters (httpserver, servlet, pushgateway, otel)
- prometheus-metrics-core: User-facing metric types
(Counter, Gauge, Histogram, Summary, Info, StateSet).
All metrics implement
Collectorwithcollect(). - prometheus-metrics-model: Internal read-only immutable
snapshot types returned by
collect(). ContainsPrometheusRegistryfor metric registration. - prometheus-metrics-config: Runtime configuration via properties files or system properties.
- prometheus-metrics-exposition-formats: Converts snapshots to Prometheus exposition formats.
- prometheus-metrics-tracer: Exemplar support with OpenTelemetry tracing integration.
- prometheus-metrics-simpleclient-bridge: Allows legacy simpleclient 0.16.0 metrics to work with the new registry.
Pre-built instrumentations:
prometheus-metrics-instrumentation-jvm, -caffeine,
-guava, -dropwizard, -dropwizard5.
- Formatter: Google Java Format (enforced via Spotless)
- Line length: 100 characters (enforced for ALL files including Markdown, Java, YAML)
- Indentation: 2 spaces
- Static analysis:
Error Pronewith NullAway (io.prometheus.metricspackage) - Logger naming: Logger fields must be named
logger(notlog,LOG, orLOGGER) - Assertions in tests: Use static imports from AssertJ
(
import static ...Assertions.assertThat) - Empty catch blocks: Use
ignoredas the variable name - Markdown code blocks: Always specify language
(e.g.,
```java,```bash,```text)
CRITICAL: These checks MUST be run before creating any commits. CI will fail if these checks fail.
- ALWAYS run
mise run buildafter modifying Java files to ensure:- Code formatting (Spotless with Google Java Format)
- Static analysis (
Error Pronewith NullAway) - Checkstyle validation
- Build succeeds (tests are skipped;
run
mise run testormise run test-allfor tests)
- ALWAYS run
mise run lintafter modifying non-Java files (runs super-linter + link checking + BOM check) mise run fixautofixes linting issues- Super-linter will autofix many issues (formatting, trailing whitespace, etc.)
- It only reports ERROR-level issues
(configured via
LOG_LEVEL=ERRORin.github/super-linter.env) - Common issues caught:
- Lines exceeding 100 characters in Markdown files
- Missing language tags in fenced code blocks
- Table formatting issues
- YAML/JSON syntax errors
# After modifying Java files (run BEFORE committing)
mise run build
# After modifying non-Java files (run BEFORE committing)
mise run lint
# or to autofix: mise run fixALWAYS run mise run lint before pushing to verify
all lints pass. CI runs the same checks and will fail
if any lint is violated.
- JUnit 5 (Jupiter) with
@Testannotations - AssertJ for fluent assertions
- Mockito for mocking
- Test visibility: Test classes and test methods must be
package-protected (no
publicmodifier) - Integration tests are in
integration-tests/and run duringverifyphase - Acceptance tests use OATs framework:
mise run acceptance-test
- Docs live under
docs/content/and use$versionas a placeholder for the library version - When publishing GitHub Pages,
mise run set-release-version-github-pagesreplaces$versionwith the latest Git tag across alldocs/content/**/*.mdfiles (the published site is not versioned) - Use
$versionfor the Prometheus client version and$otelVersion-alphafor the OTel instrumentation version — never hardcode them
Source compatibility: Java 8. Tests run on Java 25
(configured in mise.toml).