Skip to content

feat: add metrics hook#344

Draft
danjuv wants to merge 5 commits intoopen-feature:mainfrom
danjuv:feat/add-metrics-hook
Draft

feat: add metrics hook#344
danjuv wants to merge 5 commits intoopen-feature:mainfrom
danjuv:feat/add-metrics-hook

Conversation

@danjuv
Copy link
Contributor

@danjuv danjuv commented Feb 18, 2026

This PR

  • Adds an OpenFeature hook to collect OpenTelemetry metrics according to the OFEP
  • Refactors this package to split into multiple files

Related Issues

Fixes #80

Notes

  • The OFEP proposes feature_flag.variant but the TracingHook and SemConv uses feature_flag.result.variant. I've deferred to pre-existing naming in this PR instead of the proposal.
  • Other SDKs pass in an OTEL In-Memory Reader to test the Hook, since this package doesn't have a dependency on the otel-sdk, I've avoided that and mocked the metrics interface instead. This is also in-line with how we test the Tracing Hook.
  • I'm a little wary of the potentially high cardinality if we assign the exception message to every error, but I've deferred to the proposal here
  • This PR duplicates the semconv strings, since the feature flag conventions are behind a private _incubating module.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @danjuv, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new OpenTelemetry Metrics Hook to capture detailed metrics related to feature flag evaluations, aligning with the OpenFeature Enhancement Proposal (OFEP). Alongside this new functionality, the existing OpenTelemetry integration has been refactored into a more modular structure, separating tracing and metrics concerns into distinct files and centralizing common constants. This enhances the clarity, maintainability, and extensibility of the OpenTelemetry integration within the OpenFeature hooks.

Highlights

  • OpenTelemetry Metrics Hook: Implemented a new OpenFeature hook to collect OpenTelemetry metrics for flag evaluations, adhering to the OFEP specification.
  • Code Refactoring: The OpenTelemetry integration package was refactored by splitting the existing TracingHook and introducing a new MetricsHook into separate, dedicated files for better organization.
  • Standardized Constants: Introduced a constants.py file to centralize and standardize OpenTelemetry attribute and metric names, improving maintainability and consistency across the hooks.
Changelog
  • hooks/openfeature-hooks-opentelemetry/src/openfeature/contrib/hook/opentelemetry/init.py
    • Updated to import MetricsHook and TracingHook from their new respective modules.
    • Modified __all__ to export both MetricsHook and TracingHook.
    • Removed the inline TracingHook implementation and related imports.
  • hooks/openfeature-hooks-opentelemetry/src/openfeature/contrib/hook/opentelemetry/constants.py
    • Added a new file defining Attributes and Metrics classes to hold standardized OpenTelemetry attribute keys and metric names.
  • hooks/openfeature-hooks-opentelemetry/src/openfeature/contrib/hook/opentelemetry/metric.py
    • Added a new file containing the MetricsHook class, which implements OpenFeature hook methods (before, after, error, finally_after) to record various OpenTelemetry metrics (active, error, success, request totals) during flag evaluations.
  • hooks/openfeature-hooks-opentelemetry/src/openfeature/contrib/hook/opentelemetry/trace.py
    • Added a new file containing the TracingHook class, which was moved from __init__.py.
    • Updated attribute references to use the new constants.Attributes class.
  • hooks/openfeature-hooks-opentelemetry/tests/test_metric.py
    • Added a new test file with unit tests for the MetricsHook, verifying its behavior for before, after, error, and finally_after methods.
  • hooks/openfeature-hooks-opentelemetry/tests/test_otel.py
    • Renamed the existing test file for tracing to test_trace.py.
    • Updated test function names to include _trace prefix for clarity.
Activity
  • Fixed issue Implement OpenTelemetry Metrics hook #80.
  • The author noted that the OFEP proposes feature_flag.variant but deferred to feature_flag.result.variant for consistency with existing TracingHook and SemConv.
  • The author opted to mock the metrics interface for testing instead of using an OTEL In-Memory Reader, aligning with how the Tracing Hook is tested.
  • The author expressed wariness about potential high cardinality if exception messages are assigned to every error but followed the OFEP proposal.
  • The author duplicated semconv strings due to the feature flag conventions being in a private _incubating module in opentelemetry-python.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist
Copy link
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@danjuv danjuv force-pushed the feat/add-metrics-hook branch from a350b3c to aea7eb3 Compare February 18, 2026 14:16
Signed-off-by: Danju Visvanathan <danju.visvanathan@gmail.com>
@danjuv danjuv force-pushed the feat/add-metrics-hook branch from aea7eb3 to e3229fa Compare February 18, 2026 14:18
@danjuv
Copy link
Contributor Author

danjuv commented Feb 18, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new MetricsHook for OpenTelemetry and refactors the existing TracingHook into a more organized file structure. The refactoring is well-executed and improves maintainability. The new MetricsHook is a great addition. I've identified a potential high-cardinality issue with an error attribute that could impact monitoring systems, and a minor issue where a string literal is used instead of a defined constant. My review includes suggestions to address these points.

) -> None:
attributes = {
Attributes.OTEL_FLAG_KEY: hook_context.flag_key,
"exception": str(exception).lower(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using str(exception) as a metric attribute value can lead to high cardinality, which is an anti-pattern for metrics and can cause issues with your monitoring backend (e.g., performance, cost). The OpenFeature Enhancement Proposal (OFEP) for metric hooks suggests using error.type with a low-cardinality value.

To align with best practices and the OFEP, I suggest using the exception's type name instead of its string representation. This will keep the cardinality of the error.type attribute low, addressing the concern you raised in the PR description.

Suggested change
"exception": str(exception).lower(),
Attributes.OTEL_ERROR_TYPE: type(exception).__name__,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this in principle, but the OFEP specifically states to use the message

@toddbaert @beeme1mr can you confirm?

{
"feature_flag.key": "flag_key",
"feature_flag.provider.name": "test-provider",
"exception": "test error",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test should be updated to reflect the recommended change in MetricsHook.error to use error.type with the exception class name. This ensures the test validates the low-cardinality attribute.

Suggested change
"exception": "test error",
"error.type": "Exception",

Signed-off-by: Danju Visvanathan <danju.visvanathan@gmail.com>
@danjuv
Copy link
Contributor Author

danjuv commented Feb 18, 2026

Something seems wrong with CI, doesn't seem related to this PR

Signed-off-by: Danju Visvanathan <danju.visvanathan@gmail.com>
@danjuv danjuv marked this pull request as ready for review February 18, 2026 15:53
@danjuv danjuv requested review from a team as code owners February 18, 2026 15:53
@danjuv danjuv marked this pull request as draft February 19, 2026 12:30
@codecov
Copy link

codecov bot commented Feb 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (80da6b9) to head (3d016ee).

Additional details and impacted files
@@             Coverage Diff             @@
##             main      #344      +/-   ##
===========================================
+ Coverage   96.55%   100.00%   +3.44%     
===========================================
  Files           5         6       +1     
  Lines         174       220      +46     
===========================================
+ Hits          168       220      +52     
+ Misses          6         0       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement OpenTelemetry Metrics hook

2 participants

Comments