Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased](https://github.com/openfga/java-sdk/compare/v0.9.7...HEAD)

### Added
- Add `fga-client.request.count` counter metric to track the total number of HTTP requests made to the FGA server. This metric is **disabled by default** and must be explicitly enabled via `TelemetryConfiguration`.

## v0.9.7

### [0.9.7](https://github.com/openfga/java-sdk/compare/v0.9.6...v0.9.7) (2026-03-17)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ private CompletableFuture<ApiResponse<T>> processHttpResponse(
Double requestDuration = (double) (System.currentTimeMillis() - requestStarted);

telemetry.metrics().requestDuration(requestDuration, this.getTelemetryAttributes());
telemetry.metrics().requestCount(1L, this.getTelemetryAttributes());

return deserializeResponse(response)
.thenApply(modeledResponse -> new ApiResponse<>(
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/dev/openfga/sdk/telemetry/Counters.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@ public class Counters {
"fga-client.credentials.request",
"The total number of times new access tokens have been requested using ClientCredentials.");

/**
* The REQUEST_COUNT counter represents the total number of HTTP requests made by the SDK.
* This counter is emitted once per underlying HTTP request.
* Note: This counter is disabled by default and must be explicitly enabled in TelemetryConfiguration.
*/
public static final Counter REQUEST_COUNT =
new Counter("fga-client.request.count", "The total number of HTTP requests made to the FGA server.");

private Counters() {} // Instantiation prevented.
}
14 changes: 14 additions & 0 deletions src/main/java/dev/openfga/sdk/telemetry/Metrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,20 @@ public LongCounter credentialsRequest(Long value, Map<Attribute, String> attribu
return getCounter(Counters.CREDENTIALS_REQUEST, value, attributes);
}

/**
* Returns a LongCounter counter for tracking the total number of HTTP requests made to the FGA server.
* This counter is emitted once per underlying HTTP request.
* Note: This counter is disabled by default and must be explicitly enabled in TelemetryConfiguration.
*
* @param value The value to be added to the counter.
* @param attributes A map of attributes associated with the metric.
*
* @return The LongCounter metric instance for request count, or null if not configured.
*/
public LongCounter requestCount(Long value, Map<Attribute, String> attributes) {
return getCounter(Counters.REQUEST_COUNT, value, attributes);
}

/**
* Returns a DoubleHistogram histogram for measuring the total roundtrip time it took to process a request, including the time it took to send the request and receive the response.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ void testDefaultMetrics() {
assertTrue(
metrics.containsKey(Histograms.REQUEST_DURATION),
"The metrics map should contain the REQUEST_DURATION histogram.");
assertFalse(
metrics.containsKey(Counters.REQUEST_COUNT),
"The metrics map should NOT contain the REQUEST_COUNT counter by default.");

Map<Attribute, Optional<Object>> defaultAttributes = metrics.get(Counters.CREDENTIALS_REQUEST);
assertNotNull(defaultAttributes, "The default attributes map should not be null.");
Expand Down Expand Up @@ -132,6 +135,19 @@ void testDefaultMetrics() {
"The default attribute map should not contain the FGA_CLIENT_REQUEST_BATCH_CHECK_SIZE attribute.");
}

@Test
void testRequestCountCanBeExplicitlyEnabled() {
// Arrange
Map<Metric, Map<Attribute, Optional<Object>>> metrics = new HashMap<>();
metrics.put(Counters.REQUEST_COUNT, TelemetryConfiguration.defaultAttributes());
TelemetryConfiguration telemetryConfiguration = new TelemetryConfiguration(metrics);

// Assert
assertTrue(
telemetryConfiguration.metrics().containsKey(Counters.REQUEST_COUNT),
"REQUEST_COUNT should be present when explicitly configured.");
}

@Test
void testOverridingDefaultMetrics() {
// Arrange
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/dev/openfga/sdk/telemetry/CountersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,18 @@ void shouldCreateCredentialsRequestCounter() {
assertThat(counter.getName()).isEqualTo(expectedName);
assertThat(counter.getDescription()).isEqualTo(expectedDescription);
}

@Test
void shouldCreateRequestCountCounter() {
// given
String expectedName = "fga-client.request.count";
String expectedDescription = "The total number of HTTP requests made to the FGA server.";

// when
Counter counter = Counters.REQUEST_COUNT;

// then
assertThat(counter.getName()).isEqualTo(expectedName);
assertThat(counter.getDescription()).isEqualTo(expectedDescription);
}
}
30 changes: 30 additions & 0 deletions src/test/java/dev/openfga/sdk/telemetry/MetricsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,34 @@ void shouldQueryDuration() {
assertThat(doubleHistogram).isNotNull();
}

@Test
void shouldReturnNullForRequestCountWhenNotConfigured() {
// given - default configuration does not include REQUEST_COUNT
Metrics metrics = new Metrics(new Configuration());

// when
LongCounter counter = metrics.requestCount(1L, Map.of());

// then
assertThat(counter).isNull();
}

@Test
void shouldReturnRequestCountWhenExplicitlyEnabled() {
// given
Map<Attribute, Optional<Object>> attrs = Map.of();
Map<Metric, Map<Attribute, Optional<Object>>> configuredMetrics = Map.of(Counters.REQUEST_COUNT, attrs);
TelemetryConfiguration telemetryConfiguration = new TelemetryConfiguration(configuredMetrics);
Configuration config = new Configuration().telemetryConfiguration(telemetryConfiguration);
Metrics metrics = new Metrics(config);

// when
LongCounter counter = metrics.requestCount(1L, Map.of());

// then
assertThat(counter).isNotNull();
}

@Test
void shouldNotSentMetricsIfNotConfigured() {
// given
Expand Down Expand Up @@ -173,6 +201,8 @@ void shouldDefaultMetricsEnabled() {
.isNotNull();
assertThat(metrics.getHistogram(Histograms.REQUEST_DURATION, 10.0, Map.of()))
.isNotNull();
// REQUEST_COUNT is disabled by default
assertThat(metrics.getCounter(Counters.REQUEST_COUNT, 1L, Map.of())).isNull();
}

@Test
Expand Down
Loading