Skip to content

Commit 260f985

Browse files
josecolellaclaude
andauthored
docs: update README with logging hook and transaction context propagation (#232)
Signed-off-by: Jose Colella <jose.colella@gusto.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2f681c9 commit 260f985

1 file changed

Lines changed: 58 additions & 8 deletions

File tree

README.md

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ object = client.fetch_object_value(flag_key: 'object_value', default_value: { na
101101
|| [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
102102
|| [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
103103
|| [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
104-
| | [Logging](#logging) | Integrate with popular logging packages. |
104+
| | [Logging](#logging) | Integrate with popular logging packages. |
105105
|| [Domains](#domains) | Logically bind clients with providers. |
106106
|| [Eventing](#eventing) | React to state changes in the provider or flag management system. |
107107
|| [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
108108
|| [Tracking](#tracking) | Associate user actions with feature flag evaluations for experimentation. |
109-
| | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread) |
109+
| | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread) |
110110
|| [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |
111111

112112
<sub>Implemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌</sub>
@@ -247,9 +247,27 @@ client.fetch_boolean_value(
247247

248248
### Logging
249249

250-
Coming Soon! [Issue available](https://github.com/open-feature/ruby-sdk/issues/148) to work on.
250+
The SDK includes a built-in `LoggingHook` that provides structured log output for flag evaluations. It logs at the `before`, `after`, and `error` stages of the hook lifecycle.
251251

252-
<!-- TODO: talk about logging config and include a code example -->
252+
```ruby
253+
# Use the SDK's default logger (from Configuration)
254+
OpenFeature::SDK.hooks << OpenFeature::SDK::Hooks::LoggingHook.new
255+
256+
# Or provide your own logger
257+
logger = Logger.new($stdout)
258+
OpenFeature::SDK.hooks << OpenFeature::SDK::Hooks::LoggingHook.new(logger: logger)
259+
260+
# Optionally include evaluation context in log output
261+
OpenFeature::SDK.hooks << OpenFeature::SDK::Hooks::LoggingHook.new(
262+
logger: logger,
263+
include_evaluation_context: true
264+
)
265+
```
266+
267+
Log output uses a structured key=value format:
268+
- **before** (DEBUG): `stage=before domain=my-domain provider_name=my-provider flag_key=my-flag default_value=false`
269+
- **after** (DEBUG): includes `reason`, `variant`, and `value`
270+
- **error** (ERROR): includes `error_code` and `error_message`
253271

254272
### Domains
255273

@@ -361,12 +379,44 @@ Check the documentation for your [provider](#providers) for more information.
361379

362380
### Transaction Context Propagation
363381

364-
Coming Soon! [Issue available](https://github.com/open-feature/ruby-sdk/issues/150) to be worked on.
382+
Transaction context is a container for transaction-specific evaluation context (e.g. user id, user agent, IP).
383+
Transaction context can be set where specific data is available (e.g. an auth service or request handler) and by using the transaction context propagator it will automatically be applied to all flag evaluations within a transaction (e.g. a request or thread).
384+
385+
The SDK ships with a `ThreadLocalTransactionContextPropagator` that stores context in `Thread.current`:
386+
387+
```ruby
388+
# Set up the propagator
389+
OpenFeature::SDK.set_transaction_context_propagator(
390+
OpenFeature::SDK::ThreadLocalTransactionContextPropagator.new
391+
)
392+
393+
# Set transaction context (e.g. in a request middleware)
394+
OpenFeature::SDK.set_transaction_context(
395+
OpenFeature::SDK::EvaluationContext.new(targeting_key: "user-123", "email" => "user@example.com")
396+
)
397+
398+
# Transaction context is automatically merged during flag evaluation.
399+
# Merge precedence: invocation > client > transaction > API (global)
400+
client = OpenFeature::SDK.build_client
401+
client.fetch_boolean_value(flag_key: "my-flag", default_value: false)
402+
```
403+
404+
You can implement a custom propagator by including the `TransactionContextPropagator` module:
365405

366-
<!-- Transaction context is a container for transaction-specific evaluation context (e.g. user id, user agent, IP).
367-
Transaction context can be set where specific data is available (e.g. an auth service or request handler) and by using the transaction context propagator it will automatically be applied to all flag evaluations within a transaction (e.g. a request or thread). -->
406+
```ruby
407+
class MyRequestScopedPropagator
408+
include OpenFeature::SDK::TransactionContextPropagator
368409

369-
<!-- TODO: code example for global shutdown -->
410+
def set_transaction_context(evaluation_context)
411+
# Store context in your request-scoped storage
412+
RequestStore[:openfeature_context] = evaluation_context
413+
end
414+
415+
def get_transaction_context
416+
RequestStore[:openfeature_context]
417+
end
418+
end
419+
```
370420

371421
## Extending
372422

0 commit comments

Comments
 (0)