Skip to content

feat: custom labels in prometheus metrics - #2555

Merged
Lancetnik merged 5 commits into
ag2ai:mainfrom
roma-frolov:custom-labels
Oct 18, 2025
Merged

Lancetnik merged 5 commits into
ag2ai:mainfrom
roma-frolov:custom-labels

Conversation

@roma-frolov

@roma-frolov roma-frolov commented Oct 7, 2025 •

Copy link
Copy Markdown
Collaborator

Description

Fixes #2516

Type of change

  • Documentation (typos, code examples, or any documentation updates)
  • Bug fix (a non-breaking change that resolves an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a fix or feature that would disrupt existing functionality)
  • This change requires a documentation update

Checklist

  • My code adheres to the style guidelines of this project (just lint shows no errors)
  • I have conducted a self-review of my own code
  • I have made the necessary changes to the documentation
  • My changes do not generate any new warnings
  • I have added tests to validate the effectiveness of my fix or the functionality of my new feature
  • Both new and existing unit tests pass successfully on my local environment by running just test-coverage
  • I have ensured that static analysis tests are passing by running just static-analysis
  • I have included code examples to illustrate the modifications

@github-actions github-actions Bot added Confluent Issues related to `faststream.confluent` module AioKafka Issues related to `faststream.kafka` module NATS Issues related to `faststream.nats` module and NATS broker features Redis Issues related to `faststream.redis` module and Redis features Observability labels Oct 7, 2025
app_name: str = EMPTY,
metrics_prefix: str = "faststream",
received_messages_size_buckets: Sequence[float] | None = None,
custom_labels: dict[str, str | Callable[[Any], str]] | None = None,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@draincoder hi!

A similar feature in litestart allows you to pass a Callable that accepts a Request object. Which object is best to pass to FS? AnyMsg?

Comment thread faststream/prometheus/middleware.py Outdated
self._metrics_manager = metrics_manager
self._settings_provider = settings_provider_factory(msg)
self._custom_labels = {
k: str(v(msg) if callable(v) else v) for k, v in (custom_labels or {}).items()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think, we can split them in the static init method and cast here without runtime filtering

@roma-frolov roma-frolov Oct 8, 2025 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Did I understand you correctly, you mean this?:

def __init__(
        self,
        msg: AnyMsg | None,
        /,
        *,
        ...,
        static_custom_labels: dict[str, str] | None,
        dynamic_custom_labels: dict[str, Callable[[Any], str]] | None,
) -> None:
    ...
    self._custom_labels = {
        **(static_custom_labels or {}),
        **{k: str(v(msg)) for k, v in (dynamic_custom_labels or {}).items()},
    }
    ...

@Lancetnik Lancetnik Oct 8, 2025 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope, I mean

class MiddlewareBuilder:
    def __init__(self, custom_labels):
        self.static_labels = {}
        self.dynamic_labels = {}
        
        for k, v in custom_labels.items():
             if callable(v):
                 self.dynamic_labesl[k] = v
             else:
                 self.static_labesl[k] = v
      
    def __call__(self, msg):
         return RealMiddleware(msg, custom_labels = self.static_labels | {
             k: v(msg) for k, v in self.dynamic_labels.items()
         })

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done

@roma-frolov
roma-frolov marked this pull request as ready for review October 17, 2025 19:23
@roma-frolov roma-frolov self-assigned this Oct 18, 2025
@Lancetnik
Lancetnik added this pull request to the merge queue Oct 18, 2025
Merged via the queue into ag2ai:main with commit 3be12d9 Oct 18, 2025
29 checks passed
@roma-frolov
roma-frolov deleted the custom-labels branch October 19, 2025 09:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AioKafka Issues related to `faststream.kafka` module Confluent Issues related to `faststream.confluent` module NATS Issues related to `faststream.nats` module and NATS broker features Observability Redis Issues related to `faststream.redis` module and Redis features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Add custom labels for PrometheusMiddleware

2 participants