Skip to content

[feat][monitor] Add custom topic metric labels to OpenTelemetry metrics attributes#25306

Open
coderzc wants to merge 4 commits intoapache:masterfrom
coderzc:pip-447-part2
Open

[feat][monitor] Add custom topic metric labels to OpenTelemetry metrics attributes#25306
coderzc wants to merge 4 commits intoapache:masterfrom
coderzc:pip-447-part2

Conversation

@coderzc
Copy link
Member

@coderzc coderzc commented Mar 10, 2026

Main Issue: N/A

PIP: https://github.com/apache/pulsar/blob/master/pip/pip-447.md

Motivation

This PR is part 2 of PIP-447.

Part 1 for Prometheus labels has already been merged in #24991. This follow-up extends the same custom topic metric label support to OpenTelemetry topic metrics so both metrics pipelines expose the same topic property based labels.

Modifications

  • add custom topic metric labels to OpenTelemetry topic metrics for persistent topics
  • extend PersistentTopicAttributes to build OpenTelemetry attributes with custom labels
  • update OpenTelemetryTopicStats to attach custom labels across topic metrics
  • add broker tests for custom labels in OpenTelemetry metrics
  • fix the renamed config setter in the test after rebasing on latest master

Verifying this change

  • Make sure that the change passes the CI checks.

This change added tests and can be verified as follows:

  • Ran mvn clean install -DskipTests
  • Added OpenTelemetryCustomLabelsTest to verify custom labels are exposed in OpenTelemetry metrics and omitted when the feature is disabled

Does this pull request potentially affect one of the following parts:

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

Matching PR in forked repository

PR in forked repository: coderzc#51

@coderzc coderzc changed the title [feat][broker] Add custom topic metric labels to OpenTelemetry metrics [feat][monitor] Add custom topic metric labels to OpenTelemetry metrics Mar 10, 2026
@coderzc coderzc added type/feature The PR added a new feature or issue requested a new feature area/metrics labels Mar 10, 2026
@coderzc coderzc changed the title [feat][monitor] Add custom topic metric labels to OpenTelemetry metrics [feat][monitor] Add custom topic metric labels to OpenTelemetry metrics attributes Mar 10, 2026
@github-actions github-actions bot added the doc-not-needed Your PR changes do not impact docs label Mar 10, 2026
@shibd
Copy link
Member

shibd commented Mar 16, 2026

/pulsarbot rerun-failure-checks

var persistentTopicAttributes = persistentTopic.getTopicAttributes();
// For persistent topics, get custom attributes once and reuse
var customLabels = persistentTopicAttributes.getCustomAttributes();
var attributesWithCustomLabels = persistentTopicAttributes
Copy link
Member

Choose a reason for hiding this comment

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

Custom labels are only merged into the persistent-only metrics below. The AbstractTopic topic counters above (subscription, producer, consumer, message, bytes, publish rate limit) still record with attributes, so this change does not actually expose custom labels across all OpenTelemetry topic metrics.

Copy link
Member

Choose a reason for hiding this comment

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

@Test(groups = "broker")
public class OpenTelemetryCustomLabelsTest extends BrokerTestBase {

private static final Set<String> ALLOWED_CUSTOM_METRIC_LABEL_KEYS = Set.of("__SLA_TIER", "APP_OWNER");
Copy link
Member

Choose a reason for hiding this comment

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

The allow-list key here is __SLA_TIER, but the test later writes SLA_TIER. getCustomMetricLabelsMap() filters by exact property key before lowercasing for OpenTelemetry output, so this label is not actually whitelisted.

.build();

// Verify metrics contain custom labels for topic1
assertMetricLongSumValue(metrics, OpenTelemetryTopicStats.MESSAGE_IN_COUNTER, attributesTopic1, 5);
Copy link
Member

Choose a reason for hiding this comment

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

This test is asserting MESSAGE_IN_COUNTER / PRODUCER_COUNTER, but the patch only changes the persistent-topic metrics in the lower block (storage*, backlog, transaction, compaction, delayed subscription). Even if this passes, it does not verify the metrics that were actually modified here.

storageOffloadedCounter.record(managedLedger.getOffloadedSize(), attributes);
storageInCounter.record(managedLedgerStats.getReadEntriesSucceededTotal(), attributes);
storageOutCounter.record(managedLedgerStats.getAddEntrySucceedTotal(), attributes);
storageCounter.record(managedLedgerStats.getStoredMessagesSize(), attributesWithCustomLabels);
Copy link
Member

Choose a reason for hiding this comment

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

Could we push this concern down into PersistentTopicAttributes instead of threading attributesWithCustomLabels through each recorder here? TopicAttributes already exposes getCommonAttributes(), so overriding that in PersistentTopicAttributes to merge in getCustomAttributes() would let both the shared topic metrics and the persistent-only metrics pick up the custom labels automatically. That would also reduce the amount of mechanical churn in OpenTelemetryTopicStats and make it harder to miss one metric when new recorders are added later.

Copy link
Member Author

@coderzc coderzc Mar 16, 2026

Choose a reason for hiding this comment

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

Thanks, I agree the merge logic should be centralized in PersistentTopicAttributes.

My main concern is overriding getCommonAttributes(): today it is a cheap accessor over pre-built static attributes, while custom labels are dynamic and require reading topic properties. Hiding that work in a common getter makes the behavior less obvious.

I kept getCommonAttributes() unchanged, but moved the custom-label merge closer to PersistentTopicAttributes by introducing an explicit per-scrape attribute snapshot there. This keeps the dynamic work out of the common getter while also removing most of the repetitive merging from OpenTelemetryTopicStats.

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

Labels

area/metrics doc-not-needed Your PR changes do not impact docs ready-to-test type/feature The PR added a new feature or issue requested a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants