diff --git a/website/docs/advanced/proxy/endpoints.mdx b/website/docs/advanced/proxy/endpoints.mdx index 86edfb471..f81da1bdc 100644 --- a/website/docs/advanced/proxy/endpoints.mdx +++ b/website/docs/advanced/proxy/endpoints.mdx @@ -281,7 +281,220 @@ CONFIGCAT_HTTP_CDN_PROXY_HEADERS='{"Custom-Header-Name":""}' ## API -The API endpoints are for server side feature flag evaluation. +These API endpoints are for server side feature flag evaluation. + +### Endpoints using SDK key + +The following endpoints are using SDK keys to determine which config / environment is the target of the desired action. +The SDK key must be provided in the `X-ConfigCat-SdkKey` HTTP header. + +:::info +These endpoints are only available from Proxy version v3.0.0. +::: + +
+ POSTOPTIONS/api/eval + +This endpoint evaluates a single feature flag identified by a `key` with the given [User Object](../../targeting/user-object.mdx). + +**Headers**: +- `X-ConfigCat-SdkKey`: The SDK key that determines the feature flag's config / environment. + +**Request body**: +```json +{ + "key": "", + "user": { + "Identifier": "", + "Rating": 4.5, + "Roles": ["Role1","Role2"], + // any other attribute + } +} +``` + +The type of the `user` object's fields can only be `string`, `number`, or `string[]`. + +**Responses**: +
    +
  • 200: The feature flag evaluation finished successfully.
  • +
    Response body:
    + +```json +{ + "value": , + "variationId": "" +} +``` + +
  • 204: In response to an OPTIONS request.
  • +
  • 400: The X-ConfigCat-SdkKey header or the key from the request body is missing.
  • +
  • 404: The X-ConfigCat-SdkKey header is pointing to a non-existent SDK.
  • +
+ +**Example**: + +```js title="example.js" +// highlight-next-line +const url = "http://localhost:8050/api/eval"; // Proxy API URL + +const data = { + key: "isMyAwesomeFeatureEnabled", // Feature flag key + user: { // User Object for evaluation + Identifier: "#UNIQUE-USER-IDENTIFIER#" + } +}; + +const requestOptions = { + method: "POST", + headers: { + // highlight-next-line + "X-ConfigCat-SdkKey": "#YOUR-SDK-KEY#", + "Content-Type": "application/json", + }, + body: JSON.stringify(data), +}; + +try { + const response = await fetch(url, requestOptions); + const responseData = await response.json(); + console.log(responseData); // {"value":,"variationId":""} +} catch (error) { + console.error("Error:", error) +} +``` + +
+ +
+ POSTOPTIONS/api/eval-all + +This endpoint evaluates all feature flags with the given [User Object](../../targeting/user-object.mdx). + +**Headers**: +- `X-ConfigCat-SdkKey`: The SDK key that determines which config's feature flags should be evaluated in which environment. + +**Request body**: +```json +{ + "user": { + "Identifier": "", + "Rating": 4.5, + "Roles": ["Role1","Role2"], + // any other attribute + } +} +``` + +The type of the `user` object's fields can only be `string`, `number`, or `string[]`. + +**Responses**: +
    +
  • 200: The evaluation of all feature flags finished successfully.
  • +
    Response body:
    + +```json +{ + "feature-flag-key-1": { + "value": , + "variationId": "" + }, + "feature-flag-key-2": { + "value": , + "variationId": "" + } +} +``` + +
  • 204: In response to an OPTIONS request.
  • +
  • 400: The X-ConfigCat-SdkKey header is missing.
  • +
  • 404: The X-ConfigCat-SdkKey header is pointing to a non-existent SDK.
  • +
+ +**Example**: + +```js title="example.js" +// highlight-next-line +const url = "http://localhost:8050/api/eval-all"; // Proxy API URL + +const data = { + user: { // User Object for evaluation + Identifier: "#UNIQUE-USER-IDENTIFIER#" + } +}; + +const requestOptions = { + method: "POST", + headers: { + // highlight-next-line + "X-ConfigCat-SdkKey": "#YOUR-SDK-KEY#", + "Content-Type": "application/json", + }, + body: JSON.stringify(data), +}; + +try { + const response = await fetch(url, requestOptions); + const responseData = await response.json(); + console.log(responseData); +} catch (error) { + console.error("Error:", error) +} +``` + +
+ +
+ POSTOPTIONS/api/refresh + +This endpoint commands the underlying SDK to download the latest available *config JSON*. + +**Headers**: +- `X-ConfigCat-SdkKey`: The SDK key that identifies an SDK within the Proxy. + +**Responses**: + + +
+ +
+ GETOPTIONS/api/keys + +This endpoint returns all feature flag keys belonging to the given SDK key. + +**Headers**: +- `X-ConfigCat-SdkKey`: The SDK key that identifies an SDK within the Proxy. + +**Responses**: + + +
+ +### Endpoints using SDK identifier + +The following endpoints are using an [SDK identifier](overview.mdx#sdk-identifier--sdk-key) to determine which config / environment is the target of the desired action. +The SDK identifier must be provided as a route parameter of the HTTP request.
POSTOPTIONS/api/{sdkId}/eval @@ -289,7 +502,7 @@ The API endpoints are for server side feature flag evaluation. This endpoint evaluates a single feature flag identified by a `key` with the given [User Object](../../targeting/user-object.mdx). **Route parameters**: -- `sdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that uniquely identifies an SDK within the Proxy. +- `sdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that determines the feature flag's config / environment. **Request body**: ```json @@ -326,6 +539,7 @@ The type of the `user` object's fields can only be `string`, `number`, or `strin **Example**: ```js title="example.js" +// highlight-next-line const url = "http://localhost:8050/api/#SDK-IDENTIFIER#/eval"; // Proxy API URL with SDK identifier const data = { @@ -336,9 +550,9 @@ const data = { }; const requestOptions = { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify(data), }; @@ -348,7 +562,7 @@ try { const responseData = await response.json(); console.log(responseData); // {"value":,"variationId":""} } catch (error) { - console.error('Error:', error) + console.error("Error:", error) } ``` @@ -360,7 +574,7 @@ try { This endpoint evaluates all feature flags with the given [User Object](../../targeting/user-object.mdx). **Route parameters**: -- `sdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that uniquely identifies an SDK within the Proxy. +- `sdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that determines which config's feature flags should be evaluated in which environment. **Request body**: ```json @@ -402,6 +616,7 @@ The type of the `user` object's fields can only be `string`, `number`, or `strin **Example**: ```js title="example.js" +// highlight-next-line const url = "http://localhost:8050/api/#SDK-IDENTIFIER#/eval-all"; // Proxy API URL with SDK identifier const data = { @@ -411,9 +626,9 @@ const data = { }; const requestOptions = { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify(data), }; @@ -423,7 +638,7 @@ try { const responseData = await response.json(); console.log(responseData); } catch (error) { - console.error('Error:', error) + console.error("Error:", error) } ``` @@ -464,7 +679,7 @@ This endpoint returns all feature flag keys belonging to the given [SDK identifi { "keys": [ "feature-flag-key-1", - "feature-flag-key-1" + "feature-flag-key-2" ] } ``` @@ -701,6 +916,148 @@ OFREP compatibility is only available from Proxy version OpenFeature Remote Evaluation Protocol, which means it can be used with OFREP compatible OpenFeature providers. +### Endpoints using SDK key + +The following endpoints are using SDK keys to determine which config / environment is the target of the desired action. The SDK key must be provided in the `X-ConfigCat-SdkKey` HTTP header. + +:::info +These endpoints are only available from Proxy version v3.0.0. +::: + +
+ POSTOPTIONS/ofrep/v1/evaluate/flags/{key} + +This endpoint is used by OFREP compatible OpenFeature providers to evaluate a feature flag. + +**Route parameters**: +- `key`: The key of the feature flag to evaluate. + +**Headers**: +- `X-ConfigCat-SdkKey`: The SDK key that determines the feature flag's config / environment. + +**Request body**: +```json +{ + "context": { + "targetingKey": "", + "Rating": 4.5, + "Roles": ["Role1","Role2"], + } +} +``` + +**Responses**: +
    +
  • 200: The feature flag evaluation finished successfully.
  • +
    Response body:
    + +```json +{ + "key": "", + "value": , + "variant": "", + "reason": "" +} +``` + +
  • 204: In response to an OPTIONS request.
  • +
  • 400: The X-ConfigCat-SdkKey header is missing.
  • +
  • 404: The X-ConfigCat-SdkKey header is pointing to a non-existent SDK or the feature flag for key is not found.
  • +
+ +**Example**: + +```js title="example.js" +import { OpenFeature } from "@openfeature/web-sdk"; +import { OFREPWebProvider } from '@openfeature/ofrep-web-provider'; + +OpenFeature.setProvider( + new OFREPWebProvider({ + // highlight-next-line + baseUrl: "http://localhost:8050", // Proxy URL + headers: [ + // highlight-next-line + ["X-ConfigCat-SdkKey", "#YOUR-SDK-KEY#"], + ], + }), +); +``` + +
+ +
+ POSTOPTIONS/ofrep/v1/evaluate/flags + +This endpoint is used by OFREP compatible OpenFeature providers to evaluate all feature flags. + +**Headers**: +- `X-ConfigCat-SdkKey`: The SDK key that determines which config's feature flags should be evaluated in which environment. + +**Request body**: +```json +{ + "context": { + "targetingKey": "", + "Rating": 4.5, + "Roles": ["Role1","Role2"], + } +} +``` + +**Responses**: +
    +
  • 200: The evaluation of all feature flags finished successfully.
  • +
    Response body:
    + +```json +{ + "flags": [ + { + "key": "", + "value": , + "variant": "", + "reason": "" + }, + { + "key": "", + "value": , + "variant": "", + "reason": "" + } + ] +} +``` + +
  • 204: In response to an OPTIONS request.
  • +
  • 400: The X-ConfigCat-SdkKey header is missing.
  • +
  • 404: The X-ConfigCat-SdkKey header is pointing to a non-existent SDK.
  • +
+ +**Example**: + +```js title="example.js" +import { OpenFeature } from "@openfeature/web-sdk"; +import { OFREPWebProvider } from '@openfeature/ofrep-web-provider'; + +OpenFeature.setProvider( + new OFREPWebProvider({ + // highlight-next-line + baseUrl: "http://localhost:8050", // Proxy URL + headers: [ + // highlight-next-line + ["X-ConfigCat-SdkKey", "#YOUR-SDK-KEY#"], + ], + }), +); +``` + +
+ +### Endpoints using SDK identifier + +The following endpoints are using an [SDK identifier](overview.mdx#sdk-identifier--sdk-key) to determine which config / environment is the target of the desired action. +The SDK identifier must be provided in the `X-ConfigCat-SdkId` HTTP header. +
POSTOPTIONS/ofrep/v1/evaluate/flags/{key} @@ -710,7 +1067,7 @@ This endpoint is used by OFREP compatible OpenFeature providers to evaluate a fe - `key`: The key of the feature flag to evaluate. **Headers**: -- `X-ConfigCat-SdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that uniquely identifies an SDK within the Proxy. +- `X-ConfigCat-SdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that determines the feature flag's config / environment. **Request body**: ```json @@ -750,9 +1107,11 @@ import { OFREPWebProvider } from '@openfeature/ofrep-web-provider'; OpenFeature.setProvider( new OFREPWebProvider({ - baseUrl: 'http://localhost:8050', // Proxy URL + // highlight-next-line + baseUrl: "http://localhost:8050", // Proxy URL headers: [ - ['X-ConfigCat-SdkId', `#SDK-IDENTIFIER#`], + // highlight-next-line + ["X-ConfigCat-SdkId", "#SDK-IDENTIFIER#"], ], }), ); @@ -766,7 +1125,7 @@ OpenFeature.setProvider( This endpoint is used by OFREP compatible OpenFeature providers to evaluate all feature flags. **Headers**: -- `X-ConfigCat-SdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that uniquely identifies an SDK within the Proxy. +- `X-ConfigCat-SdkId`: The [SDK identifier](overview.mdx#sdk-identifier--sdk-key) that determines which config's feature flags should be evaluated in which environment. **Request body**: ```json @@ -816,9 +1175,11 @@ import { OFREPWebProvider } from '@openfeature/ofrep-web-provider'; OpenFeature.setProvider( new OFREPWebProvider({ + // highlight-next-line baseUrl: 'http://localhost:8050', // Proxy URL headers: [ - ['X-ConfigCat-SdkId', '#SDK-IDENTIFIER#'], + // highlight-next-line + ["X-ConfigCat-SdkId", "#SDK-IDENTIFIER#"], ], }), ); @@ -856,7 +1217,7 @@ CONFIGCAT_HTTP_OFREP_ENABLED= -false +true Turns the hosting of the OFREP endpoints on/off. These endpoints can be used by OFREP compatible OpenFeature providers for server side feature flag evaluation. @@ -1047,6 +1408,123 @@ CONFIGCAT_HTTP_OFREP_AUTH_HEADERS='{"X-API-KEY":""}' The SSE endpoint allows you to subscribe for feature flag value changes through Server-Sent Events connections. +### Endpoints using SDK key + +The following endpoints are using SDK keys to determine which config / environment is the target of the desired action. +The SDK key must be provided in the `sdkKey` field of the base64 encoded `data` route parameter. + +:::info +These endpoints are only available from Proxy version v3.0.0. +::: + +
+ GETOPTIONS/sse/eval/k/{data} + +This endpoint subscribes to a single flag's changes. Whenever the watched flag's value changes, the Proxy sends the new value to each connected client. + +**Route parameters**: +- `data`: The `base64` encoded input data for feature flag evaluation that must contain the SDK key, the feature flag's key, and a [User Object](../../targeting/user-object.mdx). + +**Responses**: +
    +
  • 200: The SSE connection established successfully.
  • +
    Response body:
    + +```json +{ + "value": , + "variationId": "" +} +``` + +
  • 204: In response to an OPTIONS request.
  • +
  • 400: The data, or the sdkKey or key field of data is missing.
  • +
  • 404: The sdkKey is pointing to a non-existent SDK.
  • +
+ +**Example**: +```js title="example.js" +const rawData = { + // highlight-next-line + sdkKey: "#YOUR-SDK-KEY#", + key: "isMyAwesomeFeatureEnabled", + user: { // field types can only be `string`, `number`, or `string[]`. + Identifier: "#UNIQUE-USER-IDENTIFIER#", + Rating: 4.5, + Roles: ["Role1","Role2"], + // any other attribute + } +}; + +const data = btoa(JSON.stringify(rawData)); +// highlight-next-line +const evtSource = new EventSource("http://localhost:8050/sse/eval/k/" + data); +evtSource.onmessage = (event) => { + console.log(event.data); // {"value":,"variationId":""} +}; +``` + +
+ +
+ GETOPTIONS/sse/eval-all/k/{data} + +This endpoint subscribes to all feature flags' changes behind the given SDK key. When any of the watched flags' value change, the Proxy sends its new value to each connected client. + +**Route parameters**: +- `data`: The `base64` encoded input data for feature flag evaluation that contains the SDK key and a [User Object](../../targeting/user-object.mdx). + +**Responses**: +
    +
  • 200: The SSE connection established successfully.
  • +
    Response body:
    + +```json +{ + "feature-flag-key-1": { + "value": , + "variationId": "" + }, + "feature-flag-key-2": { + "value": , + "variationId": "" + } +} +``` + +
  • 204: In response to an OPTIONS request.
  • +
  • 400: The sdkKey field of data is missing.
  • +
  • 404: The sdkKey is pointing to a non-existent SDK.
  • +
+ +**Example**: +```js title="example.js" +const rawData = { + // highlight-next-line + sdkKey: "#YOUR-SDK-KEY#", + user: { // field types can only be `string`, `number`, or `string[]`. + Identifier: "#UNIQUE-USER-IDENTIFIER#", + Rating: 4.5, + Roles: ["Role1","Role2"], + // any other attribute + } +}; + +const data = btoa(JSON.stringify(rawData)); +// highlight-next-line +const evtSource = new EventSource("http://localhost:8050/sse/eval-all/k/" + data); +evtSource.onmessage = (event) => { + console.log(event.data); // {"feature-flag-key":{"value":,"variationId":""}} +}; +``` + +
+ +### Endpoints using SDK identifier + +The following endpoints are using an SDK identifier to determine which config / environment is the target of the desired action. +The SDK identifier must be provided in the `sdkId` route parameter. +
GETOPTIONS/sse/{sdkId}/eval/{data} @@ -1076,16 +1554,17 @@ This endpoint subscribes to a single flag's changes. Whenever the watched flag's **Example**: ```js title="example.js" const rawData = { - key: "", + key: "isMyAwesomeFeatureEnabled", user: { // field types can only be `string`, `number`, or `string[]`. - Identifier: "", + Identifier: "#UNIQUE-USER-IDENTIFIER#", Rating: 4.5, Roles: ["Role1","Role2"], // any other attribute } -} +}; -const data = btoa(JSON.stringify(rawData)) +const data = btoa(JSON.stringify(rawData)); +// highlight-next-line const evtSource = new EventSource("http://localhost:8050/sse/#SDK-IDENTIFIER#/eval/" + data); evtSource.onmessage = (event) => { console.log(event.data); // {"value":,"variationId":""} @@ -1130,14 +1609,15 @@ This endpoint subscribes to all feature flags' changes behind the given [SDK ide ```js title="example.js" const rawData = { user: { // field types can only be `string`, `number`, or `string[]`. - Identifier: "", + Identifier: "#UNIQUE-USER-IDENTIFIER#", Rating: 4.5, Roles: ["Role1","Role2"], // any other attribute } -} +}; -const data = btoa(JSON.stringify(rawData)) +const data = btoa(JSON.stringify(rawData)); +// highlight-next-line const evtSource = new EventSource("http://localhost:8050/sse/#SDK-IDENTIFIER#/eval-all/" + data); evtSource.onmessage = (event) => { console.log(event.data); // {"feature-flag-key":{"value":,"variationId":""}} diff --git a/website/docs/advanced/proxy/grpc.mdx b/website/docs/advanced/proxy/grpc.mdx index cec1e83dc..6bff9e492 100644 --- a/website/docs/advanced/proxy/grpc.mdx +++ b/website/docs/advanced/proxy/grpc.mdx @@ -42,12 +42,14 @@ service FlagService { // Feature flag evaluation request message. message EvalRequest { - // The SDK identifier. - string sdk_id = 1; + // The SDK identifier. Deprecated, the field `target` should be used instead for SDK identification. + string sdk_id = 1 [ deprecated = true ]; // The feature flag's key to evaluate. string key = 2; - // The User Object. + // The user object. map user = 3; + // The evaluation request's target. + Target target = 4; } // Feature flag evaluation response message. @@ -71,8 +73,10 @@ message EvalAllResponse { // Request message for getting each available feature flag's key. message KeysRequest { - // The SDK identifier. - string sdk_id = 1; + // The SDK identifier. Deprecated, the field `target` should be used instead for SDK identification. + string sdk_id = 1 [ deprecated = true ]; + // The request's target. + Target target = 2; } // Response message that contains each available feature flag's key. @@ -83,8 +87,10 @@ message KeysResponse { // Request message for the given SDK to refresh its evaluation data. message RefreshRequest { - // The SDK identifier. - string sdk_id = 1; + // The SDK identifier. Deprecated, the field `target` should be used instead for SDK identification. + string sdk_id = 1 [ deprecated = true ]; + // The request's target. + Target target = 2; } // Defines the possible values that can be set in the `user` map. @@ -97,6 +103,16 @@ message UserValue { } } +// Identifies the target of evaluation requests by either an SDK Id or an SDK Key. +message Target { + oneof identifier { + // The SDK Id. + string sdk_id = 1; + // The SDK key. + string sdk_key = 2; + } +} + // Represents a list of strings. message StringList { repeated string values = 1; @@ -112,17 +128,10 @@ In order to secure the gRPC communication with the Proxy, set up [TLS](../../adv The following example uses a generated Go client, but gRPC clients generated for other languages are working as well. ```go title="example.go" -opts := []grpc.DialOption{ - grpc.WithBlock(), +conn, err := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ - // Any TLS options - })), -} - -conn, err := grpc.DialContext(context.Background(), - // highlight-next-line - "localhost:50051", // Proxy host and gRPC port - opts...) + // Any TLS options + }))) if err != nil { panic(err) } @@ -137,9 +146,12 @@ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err := client.EvalFlag(ctx, &proto.EvalRequest{ - SdkId: "", - Key: "", - User: map[string]*proto.UserValue{"Identifier": {Value: &proto.UserValue_StringValue{StringValue: ""}}} + // highlight-next-line + Target: &proto.Target{Identifier: &proto.Target_SdkKey{SdkKey: "#YOUR-SDK-KEY#"}}, + // Or with SDK identifier + // Target: &proto.Target{Identifier: &proto.Target_SdkId{SdkId: "#SDK-IDENTIFIER#"}}, + Key: "", + User: map[string]*proto.UserValue{"Identifier": {Value: &proto.UserValue_StringValue{StringValue: ""}}}, }) if err != nil { panic(err) diff --git a/website/docs/advanced/proxy/monitoring.mdx b/website/docs/advanced/proxy/monitoring.mdx index 10b872406..09f1e2c0d 100644 --- a/website/docs/advanced/proxy/monitoring.mdx +++ b/website/docs/advanced/proxy/monitoring.mdx @@ -9,9 +9,13 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; -The ConfigCat Proxy provides diagnostic data via its `/status` and a Prometheus-compatible `/metrics` endpoint. These endpoints are served on a specific port, so you can separate them from the public HTTP communication. +The ConfigCat Proxy provides diagnostic data including health status, metrics, and traces. -The following diagnostics related configuration options are available: +:::info +Exposed endpoints (`/status` and `/metrics`) are served on a specific port, so you can separate them from the public HTTP communication. +::: + +These are the basic diagnostic-related options: @@ -39,7 +43,7 @@ CONFIGCAT_DIAG_ENABLED= - + @@ -68,60 +72,6 @@ CONFIGCAT_DIAG_PORT=8051 - - - - - - - - - - - -
OptionDefaultDescription
trueTurns the diagnostics HTTP server on/off.Turns the collection of diagnostic data on/off.
The port used by the diagnostics HTTP server.
- - - - -```yaml -diag: - status: - enabled: -``` - - - - -```shell -CONFIGCAT_DIAG_STATUS_ENABLED= -``` - - - - -trueTurns the hosting of the status endpoint on the diagnostics HTTP server on/off.
- - - - -```yaml -diag: - metrics: - enabled: -``` - - - - -```shell -CONFIGCAT_DIAG_METRICS_ENABLED= -``` - - - - -trueTurns the Prometheus metrics on the diagnostics HTTP server on/off.
@@ -196,35 +146,112 @@ The root `status` is `healthy` if all of the SDKs are `healthy`. If any of the S
-:::note +You can control whether metrics collection should be enabled with the following configuration option: + + + + + + + + + + + + +
OptionDefaultDescription
+ + + + +```yaml +diag: + status: + enabled: +``` + + + + +```shell +CONFIGCAT_DIAG_STATUS_ENABLED= +``` + + + + +trueTurns the hosting of the status endpoint on the diagnostics HTTP server on/off.
+ +:::info You can enable the status endpoint on the main HTTP port (default: `8050`) with the [HTTP configuration options](overview.mdx#http). ::: -## Prometheus Metrics +## Metrics -You can set up the Proxy to export metrics about its internal state in Prometheus format. These metrics are served via the `/metrics` endpoint. +If enabled, the Proxy collects various metrics. These can be either exported in Prometheus format or sent to an OTLP-compatible observability backend. -The following metrics are exported: +You can control whether metric collection should be enabled with the following configuration option: + + + + + + + + + + + + +
OptionDefaultDescription
+ + + + +```yaml +diag: + metrics: + enabled: +``` + + + + +```shell +CONFIGCAT_DIAG_METRICS_ENABLED= +``` + + + + +trueTurns metrics collection on/off.
+ +### Prometheus {#prometheus-metrics} + +You can set up the Proxy to export metrics about its internal state in Prometheus format. These metrics are served on the `/metrics` endpoint. + +#### Custom Metrics + @@ -232,46 +259,95 @@ Tags: + +
NameTypeDescription
-`configcat_http_request_duration_seconds` +`configcat_stream_connections` -Histogram +Gauge -Histogram of Proxy HTTP response time in seconds.

+Number of active client connections per stream.

Tags: -- `route`: The request's URL path. -- `method`: The request's HTTP method. -- `status`: The response's HTTP status. +- `sdk`: The SDK's identifier that handles the connection. +- `type`: `sse` or `grpc`. +- `flag`: The streamed feature flag's key.
-`configcat_grpc_rpc_duration_seconds` +`configcat_stream_msg_sent_total` -Histogram +Counter -Histogram of RPC call latency in seconds.

+Total number of all messages sent with streaming.

Tags: -- `method`: The RPCs name. -- `code`: The RPCs response code. +- `sdk`: The related SDK's identifier. +- `type`: `sse` or `grpc`. +- `flag`: The evaluated feature flag's key.
+ +The Proxy also exports metrics about the Go environment, e.g., `go_goroutines` or `go_memstats_alloc_bytes`, and process-related stats, e.g., `process_cpu_seconds_total`. + +#### Integration + +To integrate with Prometheus, put the following scrape config—that points to the Proxy—into your Prometheus configuration: + +```yaml +scrape_configs: + - job_name: configcat_proxy + metrics_path: /metrics + static_configs: + - targets: + - :8051 +``` + +#### Configuration Options + + + + - - + + + +
OptionDefaultDescription
-`configcat_sdk_http_request_duration_seconds` + + - -Histogram - -Histogram of ConfigCat CDN HTTP response time in seconds.

-Tags: +```yaml +diag: + metrics: + prometheus: + enabled: +``` -- `sdk`: The SDK's identifier that initiated the request. -- `route`: The request's URL path. -- `status`: The response's HTTP status. + + + +```shell +CONFIGCAT_DIAG_METRICS_PROMETHEUS_ENABLED= +``` + + +
trueTurns the Prometheus compatible `/metrics` endpoint on the diagnostics HTTP server on/off.
+ +### OTLP + +You can set up the Proxy to send metrics via OTLP +to a compatible collector such as Amazon CloudWatch, +NewRelic, +DataDog, +or Honeycomb. + +#### Custom Metrics + + + + +
NameTypeDescription
-`configcat_stream_connections` +`stream.connections` @@ -291,7 +367,7 @@ Tags:
-`configcat_stream_msg_sent_total` +`stream.msg.sent.total` @@ -310,17 +386,255 @@ Tags:
-:::info -The Proxy also exports metrics about the Go environment, e.g., `go_goroutines` or `go_memstats_alloc_bytes`, and process-related stats, e.g., `process_cpu_seconds_total`. -::: +#### Configuration Options -To integrate with Prometheus, put the following scrape config—that points to the Proxy—into your Prometheus configuration: + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
+ + + ```yaml -scrape_configs: - - job_name: configcat_proxy - metrics_path: /metrics - static_configs: - - targets: - - :8051 -``` \ No newline at end of file +diag: + metrics: + otlp: + enabled: +``` + + + + +```shell +CONFIGCAT_DIAG_METRICS_OTLP_ENABLED= +``` + + + + +falseTurns the sending of metrics via OTLP on/off.
+ + + + +```yaml +diag: + metrics: + otlp: + protocol: "" +``` + + + + +```shell +CONFIGCAT_DIAG_METRICS_OTLP_PROTOCOL="" +``` + + + + +httpThe protocol used to send metrics over OTLP. Possible values: http, https, and grpc.
+ + + + +```yaml +diag: + metrics: + otlp: + endpoint: "localhost:4318" +``` + + + + +```shell +CONFIGCAT_DIAG_METRICS_OTLP_ENDPOINT="localhost:4318" +``` + + + + +localhost:4318The OTLP collector's endpoint.
+ +Additional OTLP-related options can be set by using the default OpenTelemetry environment variables. +For example, to set custom headers for each OTLP request, you can use the `OTEL_EXPORTER_OTLP_HEADERS` environment variable. + +```shell +OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer " +``` + +## Traces + +The Proxy is able to send traces via OTLP +to a compatible collector such as Amazon CloudWatch, +NewRelic, +DataDog, +or Honeycomb. + +You can control whether trace collection should be enabled with the following configuration option: + + + + + + + + + + + + +
OptionDefaultDescription
+ + + + +```yaml +diag: + traces: + enabled: +``` + + + + +```shell +CONFIGCAT_DIAG_TRACES_ENABLED= +``` + + + + +falseTurns trace collection on/off.
+ +#### OTLP-related Options + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
+ + + + +```yaml +diag: + traces: + otlp: + enabled: +``` + + + + +```shell +CONFIGCAT_DIAG_TRACES_OTLP_ENABLED= +``` + + + + +falseTurns the sending of traces via OTLP on/off.
+ + + + +```yaml +diag: + traces: + otlp: + protocol: "" +``` + + + + +```shell +CONFIGCAT_DIAG_TRACES_OTLP_PROTOCOL="" +``` + + + + +httpThe protocol used to send traces over OTLP. Possible values: http, https, and grpc.
+ + + + +```yaml +diag: + traces: + otlp: + endpoint: "localhost:4318" +``` + + + + +```shell +CONFIGCAT_DIAG_TRACES_OTLP_ENDPOINT="localhost:4318" +``` + + + + +localhost:4318The OTLP collector's endpoint.
+ +Additional OTLP-related options can be set by using the default OpenTelemetry environment variables. +For example, to set custom headers for each OTLP request, you can use the `OTEL_EXPORTER_OTLP_HEADERS` environment variable. + +```shell +OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer " +``` + +## OpenTelemetry Instrumentation Libraries + +Metrics and traces are also exported by the following official OpenTelemetry instrumentation libraries: +- otelhttp +- otelgrpc +- redisotel +- otelmongo +- otelaws \ No newline at end of file diff --git a/website/docs/advanced/proxy/overview.mdx b/website/docs/advanced/proxy/overview.mdx index 582cf3382..1c848d80e 100644 --- a/website/docs/advanced/proxy/overview.mdx +++ b/website/docs/advanced/proxy/overview.mdx @@ -110,7 +110,7 @@ You can then check the [status endpoint](monitoring.mdx#status) of the Proxy to This section describes the possible ways of how you can use the Proxy from your application. You can decide where you want the actual feature flag evaluation to happen. -- **Local evaluation**: Feature flags are evaluated in your application by the ConfigCat SDK running in your application. The Proxy only provides the data required for the evaluation process. +- **Local evaluation**: Feature flags are evaluated by a ConfigCat SDK running in your application. The Proxy only provides the data required for the evaluation process. - **Remote evaluation**: Feature flags are evaluated within the Proxy, your application only gets the result of the evaluation process. ### 1. Local evaluation using a ConfigCat SDK connected to the Proxy @@ -150,8 +150,8 @@ var configCatClient = configcat.getClient( You can leverage the Proxy's server side feature flag evaluation feature by sending simple HTTP requests to the Proxy's API endpoints. -```js title="example.js (Evaluating a feature flag with API)" -const url = "http://localhost:8050/api/#SDK-IDENTIFIER#/eval"; // Proxy API URL with SDK identifier +```js title="example.js (Evaluating a feature flag with API using SDK key)" +const url = "http://localhost:8050/api/eval"; // Proxy API URL with SDK identifier const data = { key: "isMyAwesomeFeatureEnabled", // Feature flag key @@ -161,9 +161,11 @@ const data = { }; const requestOptions = { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + // highlight-next-line + "X-ConfigCat-SdkKey": "#YOUR-SDK-KEY#", + "Content-Type": "application/json", }, body: JSON.stringify(data), }; @@ -173,7 +175,38 @@ try { const responseData = await response.json(); console.log(responseData); // {"value":,"variationId":""} } catch (error) { - console.error('Error:', error) + console.error("Error:", error) +} +``` + +Additionally, as the Proxy maps [unique identifiers to each configured SDK key](#sdk-identifier--sdk-key) it works with, +you can use that identifier in the API endpoint's path instead of the SDK key header. + +```js title="example.js (Evaluating a feature flag with API using SDK identifier)" +// highlight-next-line +const url = "http://localhost:8050/api/#SDK-IDENTIFIER#/eval"; // Proxy API URL + +const data = { + key: "isMyAwesomeFeatureEnabled", // Feature flag key + user: { // User Object for evaluation + Identifier: "#UNIQUE-USER-IDENTIFIER#" + } +}; + +const requestOptions = { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), +}; + +try { + const response = await fetch(url, requestOptions); + const responseData = await response.json(); + console.log(responseData); // {"value":,"variationId":""} +} catch (error) { + console.error("Error:", error) } ``` @@ -191,17 +224,36 @@ The OFREP feature of the Proxy is turned OFF by default, to use it, you have to The Proxy conforms to the OpenFeature Remote Evaluation Protocol, which means it can be used with OFREP compatible OpenFeature providers. -```js title="example.js (Initializing the OFREP JS Web provider to use the Proxy)" +```js title="example.js (Initializing the OFREP JS Web provider to use the Proxy with SDK key)" import { OpenFeature } from "@openfeature/web-sdk"; import { OFREPWebProvider } from '@openfeature/ofrep-web-provider'; OpenFeature.setProvider( new OFREPWebProvider({ // highlight-next-line - baseUrl: 'http://localhost:8050', // Proxy URL + baseUrl: "http://localhost:8050", // Proxy URL headers: [ // highlight-next-line - ['X-ConfigCat-SdkId', '#SDK-IDENTIFIER#'], + ["X-ConfigCat-SdkKey", "#YOUR-SDK-KEY#"], + ], + }), +); +``` + +Additionally, as the Proxy maps [unique identifiers to each configured SDK key](#sdk-identifier--sdk-key) it works with, +you can use that identifier in the `X-ConfigCat-SdkId` HTTP header. + +```js title="example.js (Initializing the OFREP JS Web provider to use the Proxy with SDK identifier)" +import { OpenFeature } from "@openfeature/web-sdk"; +import { OFREPWebProvider } from "@openfeature/ofrep-web-provider"; + +OpenFeature.setProvider( + new OFREPWebProvider({ + // highlight-next-line + baseUrl: "http://localhost:8050", // Proxy URL + headers: [ + // highlight-next-line + ["X-ConfigCat-SdkId", "#SDK-IDENTIFIER#"], ], }), ); @@ -213,7 +265,30 @@ You can find the available OFREP endpoints with their HTTP request/response sche The Proxy has the ability to evaluate feature flags and send notifications about subsequent evaluated flag value changes through Server-Sent Events connections. -```js title="example.js (Evaluating a feature flag and listening to changes with SSE)" +```js title="example.js (Evaluating a feature flag and listening to changes with SDK key)" +const rawData = { + // highlight-next-line + sdkKey: "#YOUR-SDK-KEY#", + key: "isMyAwesomeFeatureEnabled", // Feature flag key + user: { // User Object for evaluation + Identifier: "#UNIQUE-USER-IDENTIFIER#" + } +} + +const data = btoa(JSON.stringify(rawData)) + // highlight-next-line +const url = "http://localhost:8050/sse/eval/k"; // Proxy SSE URL + +const evtSource = new EventSource(url + "/" + data); +evtSource.onmessage = (event) => { + console.log(event.data); // {"value":,"variationId":""} +}; +``` + +Additionally, as the Proxy maps [unique identifiers to each configured SDK key](#sdk-identifier--sdk-key) it works with, +you can use that identifier in the SSE endpoint's path. + +```js title="example.js (Evaluating a feature flag and listening to changes with SDK identifier)" const rawData = { key: "isMyAwesomeFeatureEnabled", // Feature flag key user: { // User Object for evaluation @@ -222,6 +297,7 @@ const rawData = { } const data = btoa(JSON.stringify(rawData)) + // highlight-next-line const url = "http://localhost:8050/sse/#SDK-IDENTIFIER#/eval"; // Proxy SSE URL with SDK identifier const evtSource = new EventSource(url + "/" + data); @@ -386,7 +462,7 @@ It creates one SDK instance per SDK key internally and uses those for feature fl Within the Proxy, SDK keys are mapped to unique SDK identifiers. -The SDK key identifies a config/environment pair and is used to configure an SDK instance to fetch the config JSON of that config/environment pair. +The SDK key identifies a config-environment pair and is used to configure an SDK instance to fetch the config JSON of that config-environment pair. The SDK identifier identifies an SDK instance running within the Proxy and configured to use the associated SDK key. That is, the SDK identifier is effectively an alias for the associated SDK key and is used in endpoint routes to avoid exposing the SDK Key. @@ -406,6 +482,11 @@ The automatic configuration with Proxy profiles feature is only available from P The Proxy has the ability to use _Proxy profiles_ to determine which SDK keys to download and distribute. It periodically checks for profile changes, allowing it to pick up the changes on the fly, without needing a restart. +By using Proxy profiles, your deployed Proxy instances can detect and react to: +- SDK key rotation. +- Data governance change. +- Product, config and environment state changes, such as creation, renaming and deletion. + You can set up Proxy profiles under the `Manage organization` -> `Proxy Profiles` menu on the ConfigCat Dashboard. Proxy Profiles menu @@ -451,25 +532,42 @@ To connect a Proxy instance to a Proxy profile, follow these steps: Click on the edit icon in the `SDK Keys` column. Click on Select SDK Keys - Select the config/environment pairs whose SDK key you want to make available for your Proxy instance. - Select SDK Keys + You can choose SDK Keys in two ways: by creating selection rules or by choosing individual SDK Keys manually. + Your applications will have access to all feature flags in the config-environment pairs whose SDK Keys you select. - :::info - You can click config names in the first column to toggle all SDK keys in a row, or environment names in the column headers to toggle all SDK keys in a column. - ::: -
+ - ##### Selection rules + With selection rules, you can describe which existing and future config-environment pairs should be distributed to Proxy instances. + Rules can be based on products, configs and environments with the following filtering options: + - **Exact** (by selecting an exact product, config or environment): This option filters for the ID of the selected product, config or environment. It's not sensitive to renaming. + - **Any**: This option is similar to a single wildcard (`*`) expression. It filters for every product, config or environment. + - **Match expression** (by selecting `Matches`): This option matches the given pattern to the name of products/configs/environments, accepting wildcards (`*`). It's sensitive to renaming. + + Whenever a config-environment pair matches both an **Include** and an **Exclude** rule, the **Exclude** rule will always take precedence. + + Select SDK Keys +
+
+ + - ##### Manual selection + You can manually select the config-environment pairs whose SDK key you want to make available for your Proxy instance. + Select SDK Keys + + :::info + You can click config names in the first column to toggle all SDK keys in a row, or environment names in the column headers to toggle all SDK keys in a column. + ::: +
- #### Locate SDK identifiers for the selected SDK Keys - You can find the SDK identifiers generated for the selected config/environment pairs on the ConfigCat Dashboard right where you find their SDK Key. + You can find the SDK identifiers generated for the selected config-environment pairs on the ConfigCat Dashboard right where you find their SDK Key. Click on view SDK identifiers for ConfigCat Proxy - In the dialog that appears, you can find the SDK identifiers for the current config/environment pair, listed for each available Proxy profile. + In the dialog that appears, you can find the SDK identifiers for the current config-environment pair, listed for each available Proxy profile. Click on view SDK identifiers for ConfigCat Proxy

- #### (Optional) Set up how your Proxy should learn about feature flag changes - There are two ways a Proxy can detect feature flag changes. Each config/environment pair identified by each SDK key is automatically monitored for changes by periodic polling of the corresponding config JSON file at a configured frequency. + There are two ways a Proxy can detect feature flag changes. Each config-environment pair identified by each SDK key is automatically monitored for changes by periodic polling of the corresponding config JSON file at a configured frequency. Besides polling, the Proxy can receive change notifications over HTTP, via its [webhook endpoint](endpoints.mdx#webhook). - ##### Config JSON poll interval @@ -764,7 +862,7 @@ To connect a Proxy instance to a Proxy profile, follow these steps: ### 2. Manual configuration -When using environment variables, the SDK keys can be specified as a JSON object, where the **property name is the SDK identifier** (the identifier of the config/environment pair whose SDK Key the underlying SDK instance is configured to use) and the **property value is the actual SDK key**. +When using environment variables, the SDK keys can be specified as a JSON object, where the **property name is the SDK identifier** (the identifier of the config-environment pair whose SDK Key the underlying SDK instance is configured to use) and the **property value is the actual SDK key**. The **SDK identifier** part is later used in [endpoint routes](endpoints.mdx) to recognize which SDK must serve the given flag evaluation request. Furthermore, when configuring the Proxy **via environment variables**, the identifier becomes a **part of the SDK specific environment variable's name** in the following format: `CONFIGCAT__