diff --git a/specification.json b/specification.json index 570880ab..e6ccfa97 100644 --- a/specification.json +++ b/specification.json @@ -233,8 +233,8 @@ { "id": "Requirement 1.4.11", "machine_id": "requirement_1_4_11", - "content": "In the case of abnormal execution, the client SHOULD log an informative error message.", - "RFC 2119 keyword": "SHOULD", + "content": "Methods, functions, or operations on the client SHOULD NOT write log messages.", + "RFC 2119 keyword": "SHOULD NOT", "children": [] }, { diff --git a/specification/appendix-a-included-utilities.md b/specification/appendix-a-included-utilities.md index e972d01c..ce92dd67 100644 --- a/specification/appendix-a-included-utilities.md +++ b/specification/appendix-a-included-utilities.md @@ -11,7 +11,7 @@ This document contains requirements for auxiliary utilities provided by the SDK, ## In-memory provider -> Language-specific OpenFeature SDK implementations **SHOULD** expose an in-memory provider built into the SDK. +> OpenFeature SDK implementations **SHOULD** provide an `in-memory provider`. The in-memory provider is intended to be used for testing; SDK consumers may use it for their use cases. Hence, the packaging, naming, and access modifiers must be set appropriately. @@ -360,3 +360,28 @@ Providers can contain metadata. The Multi-Provider will make that metadata avail }, } ``` + +## Logging Hook + +> OpenFeature SDK implementations **SHOULD** provide a `logging hook`. + +The logging hook is a hook which logs messages during the flag evaluation life-cycle as described below: + +| Stage | Logged data | +| ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| before | `stage`, `domain`, `provider_name`, `flag_key`, `default_value` and `evaluation_context` (serialized, opt-in) | +| after | `stage`, `domain`, `provider_name`, `flag_key`, `default_value`, `evaluation_context` (serialized, opt-in), `reason`, `variant` and `value` | +| error | `stage`, `domain`, `provider_name`, `flag_key`, `default_value`, `evaluation_context` (serialized, opt-in), `error_code`, and `error_message` | +| finally | N/A | + +> The evaluation context **SHOULD** only be logged if an associated option indicates so. + +This can be a constructor option or similar, for example: `boolean printContext`. + +> If logging the evaluation context is enabled, it **MUST** be printed in such a way that it's human readable. + +Consider printing the evaluation context as a stringified JSON object, or using some other format that allows the nested properties to be easily read. + +> If the logger abstraction in the SDK supports a log level concept, the appropriate log level **SHOULD** be used for each stage (before/after: debug/info, error: error). + +Consider using `debug` or `info` levels for the `before` and `after` stages, and the `error` level for the `error` stage. diff --git a/specification/sections/01-flag-evaluation.md b/specification/sections/01-flag-evaluation.md index 43b72000..5d620d99 100644 --- a/specification/sections/01-flag-evaluation.md +++ b/specification/sections/01-flag-evaluation.md @@ -353,9 +353,15 @@ Configuration code includes code to set the provider, instantiate providers, and #### Requirement 1.4.11 -> In the case of abnormal execution, the client **SHOULD** log an informative error message. +> Methods, functions, or operations on the client **SHOULD NOT** write log messages. -Implementations may define a standard logging interface that can be supplied as an optional argument to the client creation function, which may wrap standard logging functionality of the implementation language. +The client methods (particularly the evaluation methods) run in hot code paths. +Logging (even at error level) can cause a huge volume of log entries. +For example, in a circumstance in which an application expecting a particular flag to exist is deployed in advance of that flag's being defined in the management system, logs can become inundated with `FLAG_NOT_FOUND` messages and related stack traces. +Logging in these code paths is highly discouraged. +Application authors can attach a [logging hook](../appendix-a-included-utilities.md#logging-hook) or author their own custom logging hook(s) to help with debugging or satisfy their particular logging needs. + +Logging is encouraged in functions to do with configuration, initialization, shutdown, etc. #### Requirement 1.4.12