Skip to content

Commit

Permalink
chore: add opentelemetry example app (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
ewanharris committed Jul 19, 2024
2 parents 78daf78 + f5f8b42 commit c9eaaa9
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ example/Makefile
example/README.md
example/example1/example1.mjs
example/example1/package.json
example/opentelemetry/.npmrc
example/opentelemetry/README.md
example/opentelemetry/instrumentation.mjs
example/opentelemetry/opentelemetry.mjs
example/opentelemetry/package.json
git_push.sh
index.ts
package.json
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ const fgaClient = new OpenFgaClient({

### 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/js-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/js-sdk/blob/main/docs/opentelemetry.md)

## Contributing

Expand Down
6 changes: 5 additions & 1 deletion docs/opentelemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ In cases when metrics events are sent, they will not be viewable outside of infr
| `fga-client.user` | `string` | The user that is associated with the action of the request for check and list users |
| `http.status_code ` | `int` | The status code of the response |
| `http.method` | `string` | The HTTP method for the request |
| `http.host` | `string` | Host identifier of the origin the request was sent to |
| `http.host` | `string` | Host identifier of the origin the request was sent to |

## Example

There is an [example project](https://github.com/openfga/js-sdk/blob/main/example/opentelemetry) that provides some guidance on how to configure OpenTelemetry available in the examples directory.
3 changes: 3 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ A set of Examples on how to call the OpenFGA JS SDK
Example 1:
A bare-bones example. It creates a store, and runs a set of calls against it including creating a model, writing tuples and checking for access.

OpenTelemetry:
An example that demonstrates how to integrate the OpenFGA JS SDK with OpenTelemetry.

### Running the Examples

Prerequisites:
Expand Down
11 changes: 11 additions & 0 deletions example/opentelemetry/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Configuration for OpenFGA
FGA_CLIENT_ID=
FGA_API_TOKEN_ISSUER=
FGA_API_AUDIENCE=
FGA_CLIENT_SECRET=
FGA_STORE_ID=
FGA_AUTHORIZATION_MODEL_ID=
FGA_API_URL="http://localhost:8080"

# Configuration for OpenTelemetry
OTEL_SERVICE_NAME="openfga-opentelemetry-example"
1 change: 1 addition & 0 deletions example/opentelemetry/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
43 changes: 43 additions & 0 deletions example/opentelemetry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# OpenTelemetry usage with OpenFGA's JS SDK

This example demonstrates how you can use OpenTelemetry with OpenFGA's JS SDK.

## Prerequisites

If you do not already have an OpenFGA instance running, you can start one using the following command:

```bash
docker run -d -p 8080:8080 openfga/openfga
```

You need to have an OpenTelemetry collector running to receive data. A pre-configured collector is available using Docker:

```bash
git clone https://github.com/ewanharris/opentelemetry-collector-dev-setup.git
cd opentelemetry-collector-dev-setup
docker-compose up -d
```

## Configure the example

You need to configure the example for your environment:

```bash
cp .env.example .env
```

Now edit the `.env` file and set the values as appropriate.

## Running the example

Begin by installing the required dependencies:

```bash
npm i
```

Next, run the example:

```bash
npm start
```
25 changes: 25 additions & 0 deletions example/opentelemetry/instrumentation.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import "dotenv/config";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
import process from "process";

const sdk = new NodeSDK({
metricReader: new PeriodicExportingMetricReader({
exportIntervalMillis: 5000,
exporter: new OTLPMetricExporter({
concurrencyLimit: 1,
}),
}),
});
sdk.start();

process.on("exit", () => {
sdk
.shutdown()
.then(
() => console.log("SDK shut down successfully"),
(err) => console.log("Error shutting down SDK", err)
)
.finally(() => process.exit(0));
});
80 changes: 80 additions & 0 deletions example/opentelemetry/opentelemetry.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import "dotenv/config";
import { CredentialsMethod, FgaApiValidationError, OpenFgaClient } from "@openfga/sdk";

let credentials;
if (process.env.FGA_CLIENT_ID) {
credentials = {
method: CredentialsMethod.ClientCredentials,
config: {
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
apiAudience: process.env.FGA_API_AUDIENCE,
apiTokenIssuer: process.env.FGA_API_TOKEN_ISSUER
}
};
}

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID,
credentials
});

async function main () {

setTimeout(async () => {
try {
await main();
} catch (error) {
console.log(error);
}
}, 20000);

console.log("Reading Authorization Models");
const { authorization_models } = await fgaClient.readAuthorizationModels();
console.log(`Models Count: ${authorization_models.length}`);

console.log("Reading Tuples");
const { tuples } = await fgaClient.read();
console.log(`Tuples count: ${tuples.length}`);


const checkRequests = Math.floor(Math.random() * 10);
console.log(`Making ${checkRequests} checks`);
for (let index = 0; index < checkRequests; index++) {
console.log("Checking for access" + index);
try {
const { allowed } = await fgaClient.check({
user: "user:anne",
relation: "owner",
object: "folder:foo"
});
console.log(`Allowed: ${allowed}`);
} catch (error) {
if (error instanceof FgaApiValidationError) {
console.log(`Failed due to ${error.apiErrorMessage}`);
} else {
throw error;
}
}
}

console.log("writing tuple");
await fgaClient.write({
writes: [
{
user: "user:anne",
relation: "owner",
object: "folder:date-"+Date.now(),
}
]
});
}


main()
.catch(error => {
console.error(`error: ${error}`);
process.exitCode = 1;
});
22 changes: 22 additions & 0 deletions example/opentelemetry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "openfga-opentelemetry-example",
"private": "true",
"version": "1.0.0",
"description": "A bare bones example of using the OpenFGA SDK with OpenTelemetry metrics reporting",
"author": "OpenFGA",
"license": "Apache-2.0",
"scripts": {
"start": "node --import ./instrumentation.mjs opentelemetry.mjs"
},
"dependencies": {
"@openfga/sdk": "^0.6.1",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-prometheus": "^0.52.1",
"@opentelemetry/sdk-metrics": "^1.25.1",
"@opentelemetry/sdk-node": "^0.52.1",
"dotenv": "^16.4.5"
},
"engines": {
"node": ">=16.13.0"
}
}

0 comments on commit c9eaaa9

Please sign in to comment.