···6161 service base and utilizing the provided labels provider, or by overriding the labels provider to
6262 fit your needs"""
6363 raise NotImplementedError('register_labels_service_or_provider must be implemented by the plugin')
6464+6565+6666+@hookspec(firstresult=True)
6767+def register_label_output_sink(config: Config, labels_provider: LabelsProvider) -> BaseOutputSink | None:
6868+ """
6969+ Optional: Register a custom label output sink.
7070+7171+ If a sink is returned, it will be used instead of the default LabelOutputSink.
7272+ This allows plugins to provide custom label mutation handling (e.g., with additional
7373+ analytics, webhooks, or other side effects).
7474+7575+ If None is returned or this hook is not implemented, the default LabelOutputSink is used.
7676+7777+ Args:
7878+ config: The Osprey configuration object.
7979+ labels_provider: The labels provider instance (from register_labels_service_or_provider).
8080+8181+ Returns:
8282+ A custom BaseOutputSink for handling label mutations, or None to use the default.
8383+ """
8484+ pass
···7373 load_all_osprey_plugins()
7474 sinks = flatten(plugin_manager.hook.register_output_sinks(config=config))
75757676- # Label udfs should only be registered if the labels provider is available
7676+ # Label output sink should only be added if the labels provider is available
7777 labels_provider = LABELS_PROVIDER.instance()
7878 if labels_provider:
7979- sinks.append(LabelOutputSink(labels_provider))
7979+ # Check if a custom label output sink is provided by plugins
8080+ custom_label_sink = plugin_manager.hook.register_label_output_sink(
8181+ config=config, labels_provider=labels_provider
8282+ )
8383+ if custom_label_sink:
8484+ sinks.append(custom_label_sink)
8585+ else:
8686+ sinks.append(LabelOutputSink(labels_provider))
80878188 return MultiOutputSink(sinks)
8289