From 2d44c6d14d42fbd3f5d0bdc903cc7baf94cb6987 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 16 Dec 2024 14:12:41 -0500 Subject: [PATCH 1/5] feat: add appendix D (observability) Signed-off-by: Todd Baert --- specification/README.md | 3 ++ specification/appendix-d-observability.md | 47 +++++++++++++++++++++++ specification/types.md | 2 + 3 files changed, 52 insertions(+) create mode 100644 specification/appendix-d-observability.md diff --git a/specification/README.md b/specification/README.md index eacc107e..50a2862a 100644 --- a/specification/README.md +++ b/specification/README.md @@ -16,8 +16,11 @@ sidebar_position: 0 - [Evaluation Context](./sections/03-evaluation-context.md) - [Hooks](./sections/04-hooks.md) - [Events](./sections/05-events.md) +- [Tracking](./sections/06-tracking.md) - [Appendix A: Included Utilities](./appendix-a-included-utilities.md) - [Appendix B: Gherkin Suites](./appendix-b-gherkin-suites.md) +- [Appendix C: OFREP](./appendix-c-ofrep.md) +- [Appendix D: Observability](./appendix-d-observability.md) ## Conformance diff --git a/specification/appendix-d-observability.md b/specification/appendix-d-observability.md new file mode 100644 index 00000000..e63ca93d --- /dev/null +++ b/specification/appendix-d-observability.md @@ -0,0 +1,47 @@ +--- +id: appendix-d +title: "Appendix D: Observability" +description: Conventions for OpenFeature telemetry signals +sidebar_position: 5 +--- + +# Appendix D: Observability + +This document describes conventions for extracting data from the OpenFeature SDK for use in telemetry signals. +It primarily focuses on providing recommendations for mapping well-known fields in OpenFeature to [OpenTelemetry feature-flag log records](https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-logs/) and other semantic conventions. + +## Evaluations + +Flag evaluation telemetry comprises data resolved from the provider resolution (evaluation details and flag metadata) as well as metadata about the provider itself. +This is particularly relevant to telemetry-related [hooks](./sections/04-hooks.md). + +### Evaluation Details + +The following describes how fields on the [evaluation details](types.md#evaluation-details) are mapped to feature flag log records: + +| Evaluation Details Field | Log Record Attribute | Notes | +| ------------------------ | --------------------------------------- | ---------------------------------------------------- | +| `flag key` | `feature_flag.key` | See: [flag key](./glossary.md#flag-key) | +| `error code` | `error.type` | See: [error code](./types.md#error-code) | +| `variant` | `feature_flag.variant` | See: [variant](./glossary.md#variant) | +| `error message` | `feature_flag.evaluation.error.message` | An error message associated with a failed evaluation | +| `reason` | `feature_flag.evaluation.reason` | See: [reason](./types.md#reason) | + +### Flag Metadata + +The following describes how keys in [flag metadata](types.md#flag-metadata) are mapped to feature flag log records: + +| Flag Metadata Key | Log Record Attribute | Notes | +| ----------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `contextId` | `feature_flag.context.id` | The context identifier returned in the flag metadata uniquely identifies the subject of the flag evaluation. If not available, the [targeting key](./glossary.md#targeting-key) should be used. | +| `flagSetId` | `feature_flag.set.id` | A logical identifier for the [flag set](./glossary.md#flag-set). | +| `flagSetVersion` | `feature_flag.version` | A version string (format unspecified) for the [flag set](./glossary.md#flag-set). | + +> [!NOTE] +> Keys in flag metadata use the "camelCase" casing convention, while the OpenTelemetry standard uses a namespaced "snake_case" convention. + +### Provider Metadata + +| Provider Metadata Field | Log Record Attribute | Notes | +| ----------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------ | +| `name` | `feature_flag.provider_name` | The name of the provider as defined in the `provider metadata`, available in the `hook context`. | diff --git a/specification/types.md b/specification/types.md index b434bfd6..38524c3a 100644 --- a/specification/types.md +++ b/specification/types.md @@ -58,6 +58,8 @@ A structure which contains a subset of the fields defined in the `evaluation det - variant (string, optional) - flag metadata ([flag metadata](#flag-metadata), optional) +#### Reason + A set of pre-defined reasons is enumerated below: | Reason | Explanation | From 5dc802b3643817ae595c7238ca133a2de020aa8e Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 16 Dec 2024 15:09:03 -0500 Subject: [PATCH 2/5] fixup: casing note Signed-off-by: Todd Baert --- specification/appendix-d-observability.md | 7 ++++++- specification/types.md | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/specification/appendix-d-observability.md b/specification/appendix-d-observability.md index e63ca93d..d883b4f9 100644 --- a/specification/appendix-d-observability.md +++ b/specification/appendix-d-observability.md @@ -25,7 +25,11 @@ The following describes how fields on the [evaluation details](types.md#evaluati | `error code` | `error.type` | See: [error code](./types.md#error-code) | | `variant` | `feature_flag.variant` | See: [variant](./glossary.md#variant) | | `error message` | `feature_flag.evaluation.error.message` | An error message associated with a failed evaluation | -| `reason` | `feature_flag.evaluation.reason` | See: [reason](./types.md#reason) | +| `reason` | `feature_flag.evaluation.reason` | See: [reason](./types.md#resolution-reason) | + +> [!NOTE] +> The `error.type` and `feature_flag.evaluation.reason` enumerations use a lowercase "snake_case" convention (see [OpenTelemetry feature-flag log records](https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-logs/)). +> OpenFeature [error codes](types.md#error-code) and [resolution reasons](./types.md#resolution-reason) should be transformed accordingly by integrations which include this data. ### Flag Metadata @@ -45,3 +49,4 @@ The following describes how keys in [flag metadata](types.md#flag-metadata) are | Provider Metadata Field | Log Record Attribute | Notes | | ----------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------ | | `name` | `feature_flag.provider_name` | The name of the provider as defined in the `provider metadata`, available in the `hook context`. | + \ No newline at end of file diff --git a/specification/types.md b/specification/types.md index 38524c3a..76009d37 100644 --- a/specification/types.md +++ b/specification/types.md @@ -58,7 +58,7 @@ A structure which contains a subset of the fields defined in the `evaluation det - variant (string, optional) - flag metadata ([flag metadata](#flag-metadata), optional) -#### Reason +#### Resolution Reason A set of pre-defined reasons is enumerated below: From 23efc7929b3e34c4dd89d7ee6679f207bdfec623 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 16 Dec 2024 15:15:23 -0500 Subject: [PATCH 3/5] fixup: links Signed-off-by: Todd Baert --- specification/appendix-d-observability.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specification/appendix-d-observability.md b/specification/appendix-d-observability.md index d883b4f9..ca31f7a1 100644 --- a/specification/appendix-d-observability.md +++ b/specification/appendix-d-observability.md @@ -49,4 +49,3 @@ The following describes how keys in [flag metadata](types.md#flag-metadata) are | Provider Metadata Field | Log Record Attribute | Notes | | ----------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------ | | `name` | `feature_flag.provider_name` | The name of the provider as defined in the `provider metadata`, available in the `hook context`. | - \ No newline at end of file From d71366d28f7c4b48ec5c7bfd75e4230cead26aee Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 13 Jan 2025 14:00:20 -0500 Subject: [PATCH 4/5] fixup: add type, value Signed-off-by: Todd Baert --- specification/appendix-d-observability.md | 39 ++++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/specification/appendix-d-observability.md b/specification/appendix-d-observability.md index ca31f7a1..389e85b6 100644 --- a/specification/appendix-d-observability.md +++ b/specification/appendix-d-observability.md @@ -19,33 +19,42 @@ This is particularly relevant to telemetry-related [hooks](./sections/04-hooks.m The following describes how fields on the [evaluation details](types.md#evaluation-details) are mapped to feature flag log records: -| Evaluation Details Field | Log Record Attribute | Notes | -| ------------------------ | --------------------------------------- | ---------------------------------------------------- | -| `flag key` | `feature_flag.key` | See: [flag key](./glossary.md#flag-key) | -| `error code` | `error.type` | See: [error code](./types.md#error-code) | -| `variant` | `feature_flag.variant` | See: [variant](./glossary.md#variant) | -| `error message` | `feature_flag.evaluation.error.message` | An error message associated with a failed evaluation | -| `reason` | `feature_flag.evaluation.reason` | See: [reason](./types.md#resolution-reason) | +| Log Record Attribute | Source Field or Derived Value from Evaluation Details | Notes | +| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `feature_flag.key` | `flag key` | See: [flag key](./glossary.md#flag-key) | +| `error.type` | `error code` | See: [error code](./types.md#error-code) | +| `feature_flag.variant` | `variant` | See: [variant](./glossary.md#variant) | +| `feature_flag.evaluation.error.message` | `error message` | A human-readable error message associated with a failed evaluation. For programmatic purposes, refer to `error code`. | +| `feature_flag.evaluation.reason` | `reason` | See: [reason](./types.md#resolution-reason) | +| `feature_flag.evaluation.value.type` | One of `"array"`, `"boolean"`, `"byte_array"`, `"float"`, `"int"`, `"map"`, `"null"`, `"string"` or `"unknown"`, representing the type of the `evaluation details'` `value` field | See: [reason](./types.md#resolution-reason) | > [!NOTE] > The `error.type` and `feature_flag.evaluation.reason` enumerations use a lowercase "snake_case" convention (see [OpenTelemetry feature-flag log records](https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-logs/)). > OpenFeature [error codes](types.md#error-code) and [resolution reasons](./types.md#resolution-reason) should be transformed accordingly by integrations which include this data. +#### Flag Value + +The flag value is required if the `feature_flag.variant` is not set (and optional otherwise), and is defined in a the event body: + +| Body Field | Source Field from Evaluation Details | Notes | +| ---------- | ------------------------------------ | ------------------------------------------- | +| `value` | `value` | The type of the `value` field is undefined. | + ### Flag Metadata The following describes how keys in [flag metadata](types.md#flag-metadata) are mapped to feature flag log records: -| Flag Metadata Key | Log Record Attribute | Notes | -| ----------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `contextId` | `feature_flag.context.id` | The context identifier returned in the flag metadata uniquely identifies the subject of the flag evaluation. If not available, the [targeting key](./glossary.md#targeting-key) should be used. | -| `flagSetId` | `feature_flag.set.id` | A logical identifier for the [flag set](./glossary.md#flag-set). | -| `flagSetVersion` | `feature_flag.version` | A version string (format unspecified) for the [flag set](./glossary.md#flag-set). | +| Log Record Attribute | Flag Metadata Key | Notes | +| ------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `feature_flag.context.id` | `contextId` | The context identifier returned in the flag metadata uniquely identifies the subject of the flag evaluation. If not available, the [targeting key](./glossary.md#targeting-key) should be used. | +| `feature_flag.set.id` | `flagSetId` | A logical identifier for the [flag set](./glossary.md#flag-set). | +| `feature_flag.version` | `flagSetVersion` | A version string (format unspecified) for the [flag set](./glossary.md#flag-set). | > [!NOTE] > Keys in flag metadata use the "camelCase" casing convention, while the OpenTelemetry standard uses a namespaced "snake_case" convention. ### Provider Metadata -| Provider Metadata Field | Log Record Attribute | Notes | -| ----------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------ | -| `name` | `feature_flag.provider_name` | The name of the provider as defined in the `provider metadata`, available in the `hook context`. | +| Log Record Attribute | Provider Metadata Field | Notes | +| ---------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------ | +| `feature_flag.provider_name` | `name` | The name of the provider as defined in the `provider metadata`, available in the `hook context`. | From 1418a22d92205f114f8e3f4e297dc919781b6306 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 15 Jan 2025 13:45:22 -0500 Subject: [PATCH 5/5] fixup: version Signed-off-by: Todd Baert --- specification/appendix-d-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/appendix-d-observability.md b/specification/appendix-d-observability.md index 389e85b6..a06d97a3 100644 --- a/specification/appendix-d-observability.md +++ b/specification/appendix-d-observability.md @@ -48,7 +48,7 @@ The following describes how keys in [flag metadata](types.md#flag-metadata) are | ------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `feature_flag.context.id` | `contextId` | The context identifier returned in the flag metadata uniquely identifies the subject of the flag evaluation. If not available, the [targeting key](./glossary.md#targeting-key) should be used. | | `feature_flag.set.id` | `flagSetId` | A logical identifier for the [flag set](./glossary.md#flag-set). | -| `feature_flag.version` | `flagSetVersion` | A version string (format unspecified) for the [flag set](./glossary.md#flag-set). | +| `feature_flag.version` | `version` | A version string (format unspecified) for the flag or [flag set](./glossary.md#flag-set). | > [!NOTE] > Keys in flag metadata use the "camelCase" casing convention, while the OpenTelemetry standard uses a namespaced "snake_case" convention.