Skip to content

Commit

Permalink
Merge pull request #95 from openfga/feat/improvements-to-opentelemetr…
Browse files Browse the repository at this point in the history
…y-metrics

feat: improvements to OpenTelemetry metrics
  • Loading branch information
evansims authored Aug 19, 2024
2 parents 489ca8e + f1ad4e1 commit 885f48b
Show file tree
Hide file tree
Showing 33 changed files with 1,279 additions and 193 deletions.
8 changes: 8 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ updates:
dependencies:
patterns:
- "*"
- package-ecosystem: "gradle"
directory: "/example/example1"
schedule:
interval: "monthly"
groups:
dependencies:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fossa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Set up JDK 17
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
java-version: "17"
distribution: "temurin"
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Set up JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
java-version: ${{ matrix.java }}
distribution: "temurin"
Expand Down Expand Up @@ -53,7 +53,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Set up JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
java-version: 11
distribution: "temurin"
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Set up JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
java-version: 11
distribution: "temurin"
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ VERSION.txt
# JetBrains IDEs
.idea/
*.iml

# VSCode IDE
/.vscode
21 changes: 21 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ docs/NotFoundErrorCode.md
docs/NullValue.md
docs/ObjectRelation.md
docs/OpenFgaApi.md
docs/OpenTelemetry.md
docs/PathUnknownErrorMessageResponse.md
docs/ReadAssertionsResponse.md
docs/ReadAuthorizationModelResponse.md
Expand Down Expand Up @@ -184,6 +185,7 @@ src/main/java/dev/openfga/sdk/api/configuration/Configuration.java
src/main/java/dev/openfga/sdk/api/configuration/ConfigurationOverride.java
src/main/java/dev/openfga/sdk/api/configuration/Credentials.java
src/main/java/dev/openfga/sdk/api/configuration/CredentialsMethod.java
src/main/java/dev/openfga/sdk/api/configuration/TelemetryConfiguration.java
src/main/java/dev/openfga/sdk/api/model/AbortedMessageResponse.java
src/main/java/dev/openfga/sdk/api/model/AbstractOpenApiSchema.java
src/main/java/dev/openfga/sdk/api/model/Any.java
Expand Down Expand Up @@ -272,6 +274,15 @@ src/main/java/dev/openfga/sdk/errors/FgaApiValidationError.java
src/main/java/dev/openfga/sdk/errors/FgaError.java
src/main/java/dev/openfga/sdk/errors/FgaInvalidParameterException.java
src/main/java/dev/openfga/sdk/errors/HttpStatusCode.java
src/main/java/dev/openfga/sdk/telemetry/Attribute.java
src/main/java/dev/openfga/sdk/telemetry/Attributes.java
src/main/java/dev/openfga/sdk/telemetry/Counter.java
src/main/java/dev/openfga/sdk/telemetry/Counters.java
src/main/java/dev/openfga/sdk/telemetry/Histogram.java
src/main/java/dev/openfga/sdk/telemetry/Histograms.java
src/main/java/dev/openfga/sdk/telemetry/Metric.java
src/main/java/dev/openfga/sdk/telemetry/Metrics.java
src/main/java/dev/openfga/sdk/telemetry/Telemetry.java
src/main/java/dev/openfga/sdk/util/Pair.java
src/main/java/dev/openfga/sdk/util/StringUtil.java
src/main/java/dev/openfga/sdk/util/Validation.java
Expand All @@ -290,4 +301,14 @@ src/test/java/dev/openfga/sdk/api/client/ApiClientTest.java
src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java
src/test/java/dev/openfga/sdk/api/configuration/ClientCredentialsTest.java
src/test/java/dev/openfga/sdk/api/configuration/ConfigurationTest.java
src/test/java/dev/openfga/sdk/api/configuration/TelemetryConfigurationTest.java
src/test/java/dev/openfga/sdk/telemetry/AttributeTest.java
src/test/java/dev/openfga/sdk/telemetry/AttributesTest.java
src/test/java/dev/openfga/sdk/telemetry/CounterTest.java
src/test/java/dev/openfga/sdk/telemetry/CountersTest.java
src/test/java/dev/openfga/sdk/telemetry/HistogramTest.java
src/test/java/dev/openfga/sdk/telemetry/HistogramsTest.java
src/test/java/dev/openfga/sdk/telemetry/MetricTest.java
src/test/java/dev/openfga/sdk/telemetry/MetricsTest.java
src/test/java/dev/openfga/sdk/telemetry/TelemetryTest.java
src/test/java/dev/openfga/sdk/util/StringUtilTest.java
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ This is an autogenerated Java SDK for OpenFGA. It provides a wrapper around the
- [Retries](#retries)
- [API Endpoints](#api-endpoints)
- [Models](#models)
- [OpenTelemetry](#opentelemetry)
- [Contributing](#contributing)
- [Issues](#issues)
- [Pull Requests](#pull-requests)
Expand Down Expand Up @@ -1060,6 +1061,10 @@ public class Example {



### OpenTelemetry

This SDK supports producing metrics that can be consumed as part of an [OpenTelemetry](https://opentelemetry.io/) setup. For more information, please see [the documentation](https://github.com/openfga/java-sdk/blob/main/docs/opentelemetry.md)

## Contributing

### Issues
Expand Down
12 changes: 6 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ ext {
}

dependencies {
implementation "com.google.code.findbugs:jsr305:3.0.2"
implementation "com.google.code.findbugs:jsr305:3.0.+"
implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
implementation "org.openapitools:jackson-databind-nullable:0.2.6"
implementation platform("io.opentelemetry:opentelemetry-bom:1.41.0")
implementation "org.openapitools:jackson-databind-nullable:0.2.+"
implementation platform("io.opentelemetry:opentelemetry-bom:1.41.+")
implementation "io.opentelemetry:opentelemetry-api"
}

Expand All @@ -80,7 +80,7 @@ testing {
implementation "org.junit.jupiter:junit-jupiter:$junit_version"
implementation "org.mockito:mockito-core:5.+"
runtimeOnly "org.junit.platform:junit-platform-launcher"
implementation "org.wiremock:wiremock:3.9.1"
implementation "org.wiremock:wiremock:3.9.+"

// This test-only dependency is convenient but not widely used.
// Review project activity before updating the version here.
Expand All @@ -106,8 +106,8 @@ testing {
dependencies {
implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
implementation "org.testcontainers:junit-jupiter:1.20.1"
implementation "org.testcontainers:openfga:1.20.1"
implementation "org.testcontainers:junit-jupiter:1.20.+"
implementation "org.testcontainers:openfga:1.20.+"
implementation project()
}

Expand Down
178 changes: 178 additions & 0 deletions docs/OpenTelemetry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# OpenTelemetry

This SDK produces [metrics](https://opentelemetry.io/docs/concepts/signals/metrics/) using [OpenTelemetry](https://opentelemetry.io/) that allow you to view data such as request timings. These metrics also include attributes for the model and store ID, as well as the API called to allow you to build reporting.

When an OpenTelemetry SDK instance is configured, the metrics will be exported and sent to the collector configured as part of your applications configuration. If you are not using OpenTelemetry, the metric functionality is a no-op and the events are never sent.

In cases when metrics events are sent, they will not be viewable outside of infrastructure configured in your application, and are never available to the OpenFGA team or contributors.

## Metrics

### Supported Metrics

| Metric Name | Type | Description |
| --------------------------------- | --------- | ------------------------------------------------------------------------------------ |
| `fga-client.credentials.request` | Counter | The total number of times a new token was requested when using ClientCredentials |
| `fga-client.query.duration` | Histogram | The amount of time the FGA server took to internally process nd evaluate the request |
| `fga-client.request.duration` | Histogram | The total request time for FGA requests |

### Supported attributes

| Attribute Name | Type | Description |
| ------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fga-client.request.client_id` | `string` | The client ID associated with the request, if any |
| `fga-client.request.method` | `string` | The FGA method/action that was performed (e.g. `Check`, `ListObjects`, ...) in TitleCase |
| `fga-client.request.model_id` | `string` | The authorization model ID that was sent as part of the request, if any |
| `fga-client.request.store_id` | `string` | The store ID that was sent as part of the request |
| `fga-client.response.model_id` | `string` | The authorization model ID that the FGA server used |
| `fga-client.user` | `string` | The user that is associated with the action of the request for check and list objects |
| `http.host` | `string` | Host identifier of the origin the request was sent to |
| `http.request.method` | `string` | The HTTP method for the request |
| `http.request.resend_count` | `int` | The number of retries attempted (Only sent if the request was retried. Count of `1` means the request was retried once in addition to the original request) |
| `http.response.status_code` | `int` | The status code of the response |
| `url.full` | `string` | Full URL of the request |
| `url.scheme` | `string` | HTTP Scheme of the request (`http`/`https`) |
| `user_agent.original` | `string` | User Agent used in the query |

## Examples

### Usage

Please see [the OpenTelemetry documentation](https://opentelemetry.io/docs/languages/java/) for how to configure the SDK for your application. Below is an example of how to configure the SDK to use OpenTelemetry.

In most cases you can use the `io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk` package to automatically configure OpenTelemetry.

However, if you prefer to configure OpenTelemetry manually, you can use the `io.opentelemetry.sdk.OpenTelemetrySdk` package to configure OpenTelemetry manually, as shown below.

```java
// Import the OpenFGA SDK
import dev.openfga.sdk.api.client.OpenFgaClient;
import dev.openfga.sdk.api.configuration.ClientConfiguration;

// Import the OpenTelemetry SDK
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;

public class Example {
private OpenTelemetry otel;

public static void main(String[] args) throws Exception {
ClientConfiguration config = new ClientConfiguration()
.apiUrl(System.getenv("FGA_API_URL"))
.storeId(System.getenv("FGA_STORE_ID"))
.authorizationModelId(System.getenv("FGA_MODEL_ID"));

OpenFgaClient fgaClient = new OpenFgaClient(config);

configureOpenTelemetry();

// Your application logic here ...
}

public static void configureOpenTelemetry() {
Resource resource =
Resource.getDefault().toBuilder()
.put(ServiceAttributes.SERVICE_NAME, "example-app")
.put(ServiceAttributes.SERVICE_VERSION, "0.1.0")
.build();

SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
.registerMetricReader(PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()).build())
.setResource(resource)
.build();

OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setMeterProvider(sdkMeterProvider)
.buildAndRegisterGlobal();

otel = openTelemetry;
}
}
```

### Metrics Configuration

The SDK includes a default configuration for metrics. You can override these defaults by providing your own `TelemetryConfiguration` instance.

```java
// Import the OpenFGA SDK
import dev.openfga.sdk.api.client.ApiClient;
import dev.openfga.sdk.api.configuration.ClientConfiguration;
import dev.openfga.sdk.api.configuration.TelemetryConfiguration;
import dev.openfga.sdk.telemetry.Attribute;
import dev.openfga.sdk.telemetry.Attributes;
import dev.openfga.sdk.telemetry.Counters;
import dev.openfga.sdk.telemetry.Histograms;
import dev.openfga.sdk.telemetry.Metric;

// Import the OpenTelemetry SDK
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class Example {
private OpenTelemetry otel;

public static void main(String[] args) {
ClientConfiguration config = new ClientConfiguration()
.apiUrl(System.getenv("FGA_API_URL"))
.storeId(System.getenv("FGA_STORE_ID"))
.authorizationModelId(System.getenv("FGA_MODEL_ID"))
.telemetryConfiguration(buildOpenTelemetryConfiguration()); // Supply your custom TelemetryConfiguration

OpenFgaClient fgaClient = new OpenFgaClient(config);

configureOpenTelemetry();

// Your application logic here ...
}

public static TelemetryConfiguration buildOpenTelemetryConfiguration() {
Map<Attribute, Optional<Object>> attributes = new HashMap<>();
attributes.put(Attributes.FGA_CLIENT_REQUEST_CLIENT_ID, Optional.empty());
attributes.put(Attributes.FGA_CLIENT_REQUEST_METHOD, Optional.empty());
attributes.put(Attributes.FGA_CLIENT_REQUEST_MODEL_ID, Optional.empty());
attributes.put(Attributes.FGA_CLIENT_REQUEST_STORE_ID, Optional.empty());
attributes.put(Attributes.FGA_CLIENT_RESPONSE_MODEL_ID, Optional.empty());
attributes.put(Attributes.HTTP_HOST, Optional.empty());
attributes.put(Attributes.HTTP_REQUEST_RESEND_COUNT, Optional.empty());
attributes.put(Attributes.HTTP_RESPONSE_STATUS_CODE, Optional.empty());
attributes.put(Attributes.URL_FULL, Optional.empty());
attributes.put(Attributes.URL_SCHEME, Optional.empty());
attributes.put(Attributes.USER_AGENT, Optional.empty());

Map<Metric, Map<Attribute, Optional<Object>>> metrics = new HashMap<>();
metrics.put(Counters.CREDENTIALS_REQUEST, attributes);
metrics.put(Histograms.QUERY_DURATION, attributes);
metrics.put(Histograms.REQUEST_DURATION, attributes);

return new TelemetryConfiguration(metrics);
}

public static void configureOpenTelemetry() {
Resource resource =
Resource.getDefault().toBuilder()
.put(ServiceAttributes.SERVICE_NAME, "example-app")
.put(ServiceAttributes.SERVICE_VERSION, "0.1.0")
.build();

SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
.registerMetricReader(PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()).build())
.setResource(resource)
.build();

OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setMeterProvider(sdkMeterProvider)
.buildAndRegisterGlobal();

otel = openTelemetry;
}
}
```
4 changes: 2 additions & 2 deletions example/example1/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ repositories {
}

ext {
jacksonVersion = "2.16.0"
jacksonVersion = "2.17.1"
}

dependencies {
implementation("dev.openfga:openfga-sdk:0.4.+")
implementation("dev.openfga:openfga-sdk:0.5.0")

// Serialization
implementation("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
Expand Down
Loading

0 comments on commit 885f48b

Please sign in to comment.