From fbda93946004a8ecb9d0b9b6ab1320a7ace7350b Mon Sep 17 00:00:00 2001 From: vil02 <65706193+vil02@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:17:20 +0100 Subject: [PATCH 1/5] fix: update links to `SECURITY.md` --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 305178e..82cac46 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,4 +43,4 @@ Please do not open issues for general support or usage questions. Instead, join ### Vulnerability Reporting -Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://github.com/openfga/go-sdk/blob/main/.github/SECURITY.md) details the procedure for disclosing security issues. +Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://github.com/openfga/.github/blob/main/SECURITY.md) details the procedure for disclosing security issues. From 5ff21d05555c13df5c505b5626a5ad467bbc13c6 Mon Sep 17 00:00:00 2001 From: vil02 <65706193+vil02@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:18:18 +0100 Subject: [PATCH 2/5] fix: update `Stores` links --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 74538c1..a878f9d 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,7 @@ If your server is configured with [authentication enabled](https://openfga.dev/d Get a paginated list of stores. -[API Documentation](https://openfga.dev/api/service/docs/api#/Stores/ListStores) +[API Documentation](https://openfga.dev/api/service#/Stores/ListStores) ```golang options := ClientListStoresOptions{ @@ -248,7 +248,7 @@ stores, err := fgaClient.ListStores(context.Background()).Options(options).Execu Create and initialize a store. -[API Documentation](https://openfga.dev/api/service/docs/api#/Stores/CreateStore) +[API Documentation](https://openfga.dev/api/service#/Stores/CreateStore) ```golang body := ClientCreateStoreRequest{Name: "FGA Demo"} @@ -269,7 +269,7 @@ fgaClient.SetStoreId(store.Id) Get information about the current store. -[API Documentation](https://openfga.dev/api/service/docs/api#/Stores/GetStore) +[API Documentation](https://openfga.dev/api/service#/Stores/GetStore) ```golang options := ClientGetStoreOptions{ @@ -288,7 +288,7 @@ if err != nil { Delete a store. -[API Documentation](https://openfga.dev/api/service/docs/api#/Stores/DeleteStore) +[API Documentation](https://openfga.dev/api/service#/Stores/DeleteStore) ```golang options := ClientDeleteStoreOptions{ @@ -508,7 +508,7 @@ By default, write runs in a transaction mode where any invalid operation (deleti ```golang body := ClientWriteRequest{ - Writes: []ClientTupleKey{ { + Writes: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "viewer", Object: "document:roadmap", @@ -517,7 +517,7 @@ body := ClientWriteRequest{ Relation: "viewer", Object: "document:budget", } }, - Deletes: []ClientTupleKeyWithoutCondition{ { + Deletes: &[]ClientTupleKeyWithoutCondition{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "writer", Object: "document:roadmap", @@ -541,7 +541,7 @@ The SDK will split the writes into separate chunks and send them in separate req ```golang body := ClientWriteRequest{ - Writes: []ClientTupleKey{ { + Writes: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "viewer", Object: "document:roadmap", @@ -550,7 +550,7 @@ body := ClientWriteRequest{ Relation: "viewer", Object: "document:budget", } }, - Deletes: []ClientTupleKeyWithoutCondition{ { + Deletes: &[]ClientTupleKeyWithoutCondition{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "writer", Object: "document:roadmap", @@ -602,7 +602,7 @@ body := ClientCheckRequest{ User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "viewer", Object: "document:roadmap", - ContextualTuples: []ClientTupleKey{ { + ContextualTuples: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "editor", Object: "document:roadmap", @@ -640,7 +640,7 @@ body := ClientBatchCheckBody{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "viewer", Object: "document:roadmap", - ContextualTuples: []ClientTupleKey{ { + ContextualTuples: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "editor", Object: "document:roadmap", @@ -649,7 +649,7 @@ body := ClientBatchCheckBody{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "admin", Object: "document:roadmap", - ContextualTuples: []ClientTupleKey{ { + ContextualTuples: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "editor", Object: "document:roadmap", @@ -753,7 +753,7 @@ body := ClientListObjectsRequest{ User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "can_read", Type: "document", - ContextualTuples: []ClientTupleKey{ { + ContextualTuples: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "editor", Object: "folder:product", @@ -788,7 +788,7 @@ body := ClientListRelationsRequest{ User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Object: "document:roadmap", Relations: []string{"can_view", "can_edit", "can_delete", "can_rename"}, - ContextualTuples: []ClientTupleKey{ { + ContextualTuples: &[]ClientTupleKey{ { User: "user:81684243-9356-4421-8fbf-a4f8d36aa31b", Relation: "editor", Object: "document:roadmap", @@ -1038,7 +1038,7 @@ Class | Method | HTTP request | Description ### 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/go-sdk/blob/main/docs/OpenTelemetry.md) +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/go-sdk/blob/main/docs/opentelemetry.md) ## Contributing From 49204d07ac5cdfb9a1750781af47145a618b1932 Mon Sep 17 00:00:00 2001 From: Ewan Harris Date: Wed, 9 Oct 2024 10:20:48 +0100 Subject: [PATCH 3/5] chore: update generated files and otel docs --- .openapi-generator/FILES | 25 +++++++++ docs/OpenTelemetry.md | 99 +++++++++++++++++++++++++++++++++--- example/example1/go.mod | 11 +++- example/example1/go.sum | 23 +++++++++ example/opentelemetry/go.mod | 5 +- example/opentelemetry/go.sum | 2 + telemetry/attributes.go | 2 +- telemetry/interfaces.go | 46 ++++++++--------- 8 files changed, 178 insertions(+), 35 deletions(-) diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index f70d356..ef16cd0 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -102,10 +102,13 @@ docs/WriteAuthorizationModelResponse.md docs/WriteRequest.md docs/WriteRequestDeletes.md docs/WriteRequestWrites.md +docs/opentelemetry.md example/Makefile example/README.md example/example1/example1.go example/example1/go.mod +example/opentelemetry/go.mod +example/opentelemetry/main.go git_push.sh go.mod go.sum @@ -208,4 +211,26 @@ oauth2/token_test.go oauth2/transport.go oauth2/transport_test.go response.go +telemetry/attribute.go +telemetry/attribute_test.go +telemetry/attributes.go +telemetry/attributes_test.go +telemetry/configuration.go +telemetry/configuration_test.go +telemetry/counter.go +telemetry/counter_test.go +telemetry/counters.go +telemetry/counters_test.go +telemetry/histogram.go +telemetry/histogram_test.go +telemetry/histograms.go +telemetry/histograms_test.go +telemetry/interfaces.go +telemetry/interfaces_test.go +telemetry/metric.go +telemetry/metric_test.go +telemetry/metrics.go +telemetry/metrics_test.go +telemetry/telemetry.go +telemetry/telemetry_test.go utils.go diff --git a/docs/OpenTelemetry.md b/docs/OpenTelemetry.md index 7afed5e..860fafe 100644 --- a/docs/OpenTelemetry.md +++ b/docs/OpenTelemetry.md @@ -1,10 +1,21 @@ # 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. +- [Overview](#overview) +- [Metrics](#metrics) + - [Supported Metrics](#supported-metrics) + - [Supported Attributes](#supported-attributes) +- [Customizing Reporting](#customizing-reporting) +- [Usage](#usage) + - [Installation](#1-install-dependencies) + - [Configure OpenTelemetry](#2-configure-opentelemetry) + - [Configure OpenFGA](#3-configure-openfga) +- [Example Integration](#example-integration) -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. +## Overview -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. +This SDK supports [OpenTelemetry](https://opentelemetry.io/) to export [metrics](https://opentelemetry.io/docs/concepts/signals/metrics/) that provide insights into your application's performance, such as request timings. These metrics include attributes like model and store IDs, and the API called, which you can use to build detailed reports and dashboards. + +If you configure the OpenTelemetry SDK, these metrics will be exported and sent to a collector as specified in your application's configuration. If OpenTelemetry is not configured, metrics functionality is disabled, and no events are sent. ## Metrics @@ -31,13 +42,87 @@ In cases when metrics events are sent, they will not be viewable outside of infr | `http.request.method` | string | Yes | HTTP method for the request | | `http.request.resend_count` | int | Yes | Number of retries attempted, if any | | `http.response.status_code` | int | Yes | Status code of the response (e.g., `200` for success) | -| `http.server.request.duration` | int | No | Time taken by the FGA server to process and evaluate the request, in milliseconds | +| `http.server.request.duration` | int | Yes | Time taken by the FGA server to process and evaluate the request, in milliseconds | | `url.scheme` | string | Yes | HTTP scheme of the request (`http`/`https`) | | `url.full` | string | Yes | Full URL of the request | | `user_agent.original` | string | Yes | User Agent used in the query | -## Example +## Customizing Reporting + +To control which metrics and attributes are reported by the SDK, you can provide your own `TelemetryConfiguration` instance during initialization, as shown in the example above. The `TelemetryConfiguration` class allows you to configure the metrics and attributes that are reported by the SDK, as outlined in [the tables above](#metrics). + +## Usage + +### 1. Install Dependencies + +Install the OpenFGA SDK and OpenTelemetry SDK in your application using `pip`: + +```sh +go get "github.com/openfg/go-sdk" \ + "go.opentelemetry.io/otel" \ + "go.opentelemetry.io/otel/sdk/metric" + ``` + +You must also install an OpenTelemetry exporter; for example, the OTLP gRPC exporter: + +```sh +go get "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" +``` + +### 2. Configure OpenTelemetry + +Configure your application to use OpenTelemetry, and set up the metrics provider to export metrics using an exporter: + +```go +package main + +import ( + "context" + "errors" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + "go.opentelemetry.io/otel/sdk/metric" +) + +// Configure OpenTelemetry +metricExporter, _ := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(conn)) + +meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)), + sdkmetric.WithResource(res), +) +otel.SetMeterProvider(meterProvider) +defer meterProvider.Shutdown() +``` + +### 3. Configure OpenFGA + +Configure the OpenFGA client, and (optionally) customize what metrics and attributes are reported: + +```go +import ( + "github.com/openfga/go-sdk/client" + "os" +) + +fgaClient, err := NewSdkClient(&ClientConfiguration{ + ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example + StoreId: os.Getenv("FGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores` + AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, recommended to be set for production + Telemetry: &telemetry.Configuration{ + Metrics: &telemetry.MetricsConfiguration{ + METRIC_HISTOGRAM_REQUEST_DURATION: &telemetry.MetricConfiguration{ + ATTR_FGA_CLIENT_REQUEST_CLIENT_ID: &telemetry.AttributeConfiguration{Enabled: true}, + ATTR_HTTP_RESPONSE_STATUS_CODE: &telemetry.AttributeConfiguration{Enabled: true}, + } + } + } +}) + +``` -You can find a basic example integration in the [examples/opentelemetry](../../examples/opentelemetry) directory, which demonstrates how to configure the OpenFGA SDK with OpenTelemetry. +## Example Integration -Please see [the OpenTelemetry documentation](https://opentelemetry.io/docs/languages/go/) for additional details on how to further configure their SDK for your applications. +An [example integration](../example/opentelemetry) is provided that also demonstrates how to configure an application with OpenFGA and OpenTelemetry. Please refer to [the README](../example/opentelemetry/README.md) for more information. diff --git a/example/example1/go.mod b/example/example1/go.mod index 3fa01e1..1180d3a 100644 --- a/example/example1/go.mod +++ b/example/example1/go.mod @@ -4,7 +4,14 @@ go 1.22.2 require github.com/openfga/go-sdk v0.6.1 -require golang.org/x/sync v0.8.0 // indirect +require ( + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect + golang.org/x/sync v0.8.0 // indirect +) // To reference local build, uncomment below and run `go mod tidy` -replace github.com/openfga/go-sdk v0.6.1 => ../../ +// replace github.com/openfga/go-sdk v0.6.1 => ../../ diff --git a/example/example1/go.sum b/example/example1/go.sum index 20ef020..665f37e 100644 --- a/example/example1/go.sum +++ b/example/example1/go.sum @@ -1,4 +1,27 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/openfga/go-sdk v0.6.1 h1:AlCjX4auM7X9sktHLx9YvFjvU+FoMGuvQ8QkJD627Lo= +github.com/openfga/go-sdk v0.6.1/go.mod h1:zui7pHE3eLAYh2fFmEMrWg9XbxYns2WW5Xr/GEgili4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/example/opentelemetry/go.mod b/example/opentelemetry/go.mod index 5cf93ad..233a3b6 100644 --- a/example/opentelemetry/go.mod +++ b/example/opentelemetry/go.mod @@ -2,11 +2,12 @@ module openfga-opentelemetry-example go 1.21 -replace github.com/openfga/go-sdk => ../.. +// To reference local build, uncomment below and run `go mod tidy` +// replace github.com/openfga/go-sdk v0.6.1 => ../../ require ( github.com/joho/godotenv v1.5.1 - github.com/openfga/go-sdk v0.0.0-00010101000000-000000000000 + github.com/openfga/go-sdk v0.6.1 go.opentelemetry.io/otel v1.29.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 go.opentelemetry.io/otel/sdk v1.29.0 diff --git a/example/opentelemetry/go.sum b/example/opentelemetry/go.sum index 0c8ae80..08d3993 100644 --- a/example/opentelemetry/go.sum +++ b/example/opentelemetry/go.sum @@ -17,6 +17,8 @@ github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInw github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/openfga/go-sdk v0.6.1 h1:AlCjX4auM7X9sktHLx9YvFjvU+FoMGuvQ8QkJD627Lo= +github.com/openfga/go-sdk v0.6.1/go.mod h1:zui7pHE3eLAYh2fFmEMrWg9XbxYns2WW5Xr/GEgili4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= diff --git a/telemetry/attributes.go b/telemetry/attributes.go index 2a4e3f8..033cec0 100644 --- a/telemetry/attributes.go +++ b/telemetry/attributes.go @@ -244,7 +244,7 @@ func (m *Metrics) AttributesFromResendCount(resendCount int, attrs map[*Attribut } func (m *Metrics) BuildTelemetryAttributes(requestMethod string, methodParameters map[string]interface{}, req *http.Request, res *http.Response, requestStarted time.Time, resendCount int) (map[*Attribute]string, float64, float64, error) { - var attrs = make(map[*Attribute]string) + var attrs map[*Attribute]string attrs, _ = m.AttributesFromRequest(req, methodParameters) attrs, _ = m.AttributesFromResponse(res, attrs) diff --git a/telemetry/interfaces.go b/telemetry/interfaces.go index c580ed7..23b9218 100644 --- a/telemetry/interfaces.go +++ b/telemetry/interfaces.go @@ -1,23 +1,23 @@ -package telemetry - -/* -CheckRequestTupleKeyInterface is a simplified interface that defines the methods the CheckRequestTupleKey struct implements, relevant to the context of the telemetry package. -*/ -type CheckRequestTupleKeyInterface interface { - GetUser() *string -} - -/* -CheckRequestInterface is a simplified interface that defines the methods the CheckRequest struct implements, relevant to the context of the telemetry package. -*/ -type CheckRequestInterface interface { - GetTupleKey() CheckRequestTupleKeyInterface - RequestAuthorizationModelIdInterface -} - -/* -RequestAuthorizationModelIdInterface is a generic interface that defines the GetAuthorizationModelId() method a Request struct implements, relevant to the context of the telemetry package. -*/ -type RequestAuthorizationModelIdInterface interface { - GetAuthorizationModelId() *string -} +package telemetry + +/* +CheckRequestTupleKeyInterface is a simplified interface that defines the methods the CheckRequestTupleKey struct implements, relevant to the context of the telemetry package. +*/ +type CheckRequestTupleKeyInterface interface { + GetUser() *string +} + +/* +CheckRequestInterface is a simplified interface that defines the methods the CheckRequest struct implements, relevant to the context of the telemetry package. +*/ +type CheckRequestInterface interface { + GetTupleKey() CheckRequestTupleKeyInterface + RequestAuthorizationModelIdInterface +} + +/* +RequestAuthorizationModelIdInterface is a generic interface that defines the GetAuthorizationModelId() method a Request struct implements, relevant to the context of the telemetry package. +*/ +type RequestAuthorizationModelIdInterface interface { + GetAuthorizationModelId() *string +} From 2349656dc55d571e45cf49a5fc9b7d09534118f6 Mon Sep 17 00:00:00 2001 From: Ewan Harris Date: Wed, 9 Oct 2024 10:35:42 +0100 Subject: [PATCH 4/5] fix: correctly set consistency on batch check --- client/client.go | 20 +++++++++++++------- client/client_test.go | 12 +++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/client/client.go b/client/client.go index 89abd4a..fb70bdc 100644 --- a/client/client.go +++ b/client/client.go @@ -2018,17 +2018,23 @@ func (client *OpenFgaClient) BatchCheckExecute(request SdkClientBatchCheckReques return nil, err } + checkOptions := &ClientCheckOptions{ + AuthorizationModelId: authorizationModelId, + StoreId: storeId, + } + + if request.GetOptions() != nil && request.GetOptions().Consistency != nil { + checkOptions.Consistency = request.GetOptions().Consistency + } + for index, checkBody := range *request.GetBody() { index, checkBody := index, checkBody group.Go(func() error { singleResponse, err := client.CheckExecute(&SdkClientCheckRequest{ - ctx: ctx, - Client: client, - body: &checkBody, - options: &ClientCheckOptions{ - AuthorizationModelId: authorizationModelId, - StoreId: storeId, - }, + ctx: ctx, + Client: client, + body: &checkBody, + options: checkOptions, }) if _, ok := err.(fgaSdk.FgaApiAuthenticationError); ok { diff --git a/client/client_test.go b/client/client_test.go index a9076cb..dbf9474 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -2202,7 +2202,7 @@ func TestOpenFgaClient(t *testing.T) { options := ClientBatchCheckOptions{ AuthorizationModelId: openfga.PtrString(authModelId), MaxParallelRequests: openfga.PtrInt32(5), - Consistency: openfga.CONSISTENCYPREFERENCE_UNSPECIFIED.Ptr(), + Consistency: openfga.CONSISTENCYPREFERENCE_HIGHER_CONSISTENCY.Ptr(), } var expectedResponse openfga.CheckResponse @@ -2213,7 +2213,7 @@ func TestOpenFgaClient(t *testing.T) { httpmock.Activate() defer httpmock.DeactivateAndReset() httpmock.RegisterMatcherResponder(test.Method, fmt.Sprintf("%s/stores/%s/%s", fgaClient.GetConfig().ApiUrl, getStoreId(t, fgaClient), test.RequestPath), - httpmock.BodyContainsString(`"consistency":"UNSPECIFIED"`), + httpmock.BodyContainsString(`"consistency":"HIGHER_CONSISTENCY"`), func(req *http.Request) (*http.Response, error) { resp, err := httpmock.NewJsonResponse(test.ResponseStatus, expectedResponse) if err != nil { @@ -2223,10 +2223,16 @@ func TestOpenFgaClient(t *testing.T) { }, ) - _, err := fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(options).Execute() + checks, err := fgaClient.BatchCheck(context.Background()).Body(requestBody).Options(options).Execute() if err != nil { t.Fatalf("%v", err) } + + for _, check := range *checks { + if check.Error != nil { + t.Fatalf("a check failed %v", check.Error) + } + } }) t.Run("Expand", func(t *testing.T) { From a32857397041d9732af83a0028e2c93f4a6c7113 Mon Sep 17 00:00:00 2001 From: Ewan Harris Date: Wed, 9 Oct 2024 14:29:59 +0100 Subject: [PATCH 5/5] docs: update docs table with latest contents --- docs/OpenTelemetry.md | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/docs/OpenTelemetry.md b/docs/OpenTelemetry.md index 860fafe..cab5599 100644 --- a/docs/OpenTelemetry.md +++ b/docs/OpenTelemetry.md @@ -1,21 +1,10 @@ # OpenTelemetry -- [Overview](#overview) -- [Metrics](#metrics) - - [Supported Metrics](#supported-metrics) - - [Supported Attributes](#supported-attributes) -- [Customizing Reporting](#customizing-reporting) -- [Usage](#usage) - - [Installation](#1-install-dependencies) - - [Configure OpenTelemetry](#2-configure-opentelemetry) - - [Configure OpenFGA](#3-configure-openfga) -- [Example Integration](#example-integration) +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. -## Overview +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. -This SDK supports [OpenTelemetry](https://opentelemetry.io/) to export [metrics](https://opentelemetry.io/docs/concepts/signals/metrics/) that provide insights into your application's performance, such as request timings. These metrics include attributes like model and store IDs, and the API called, which you can use to build detailed reports and dashboards. - -If you configure the OpenTelemetry SDK, these metrics will be exported and sent to a collector as specified in your application's configuration. If OpenTelemetry is not configured, metrics functionality is disabled, and no events are 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 @@ -42,7 +31,7 @@ If you configure the OpenTelemetry SDK, these metrics will be exported and sent | `http.request.method` | string | Yes | HTTP method for the request | | `http.request.resend_count` | int | Yes | Number of retries attempted, if any | | `http.response.status_code` | int | Yes | Status code of the response (e.g., `200` for success) | -| `http.server.request.duration` | int | Yes | Time taken by the FGA server to process and evaluate the request, in milliseconds | +| `http.server.request.duration` | int | No | Time taken by the FGA server to process and evaluate the request, in milliseconds | | `url.scheme` | string | Yes | HTTP scheme of the request (`http`/`https`) | | `url.full` | string | Yes | Full URL of the request | | `user_agent.original` | string | Yes | User Agent used in the query |