Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stats: introduce CustomStatNamespaces. #17357

Merged
merged 46 commits into from
Sep 13, 2021

Conversation

mathetake
Copy link
Member

@mathetake mathetake commented Jul 15, 2021

This commit adds Stats::CustomStatNamespaces, and the concept of custom stat namespaces used by
extensions and stat sinks. Custom stat namespaces are registered by extensions
via the Stats::CustomStatNamespaces object owned by the API object, and user-defined metrics
created by these extensions are all prefixed by the namespace. For example,
Wasm extension registers "wasmcustom" as a custom stat namespace,
and all the metrics created by user Wasm programs are prefixed by "wasmcustom." internally.
This is mainly for distinguishing these "custom metrics" defined outside Envoy codebase from
the native metrics defined by Envoy codebase, and this way stat sinks are able to determine
how to expose these two kinds of metrics.

Notably this commit fixes #14920 and istio/istio#27635 by making changes to
prometheus stat handler so that it strips the metrics names prefixed
by custom stat namespaces and exposes the stripped ones as-is in the output.
Previously in the prometheus stat handler, Envoy prefixes all the metrics by "envoy_" for those who do not have
the prefixes registered statistically via PrometheusStatsFormatter::registerPrometheusNamespace.
That was not a good UX because, for example, Wasm extension users cannot register their own
prometheus namespaces at runtime and therefore they end up having
all of their own metrics prefixed by "envoy_" unless they have their own Envoy builds.
Consequently, we no longer need the static prometheus namespace registration mechanism,
so this commit also deletes the unneeded API.

Signed-off-by: Takeshi Yoneda [email protected]

@mathetake
Copy link
Member Author

@lizan could you take a quick view to see if my approach to thread-safety looks ok? I guess something like "dispatch on main thread" would be another approach rather than taking mutex like this, but I couldn't find the proper way to do that.

Copy link
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

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

I'm not keen into this approach, doesn't the wasm foreign function implementation has access to dispatcher?

source/server/admin/prometheus_stats.cc Outdated Show resolved Hide resolved
@mathetake
Copy link
Member Author

yeah actually we can access to the main thread dispatcher here. Let me rework later.

@mathetake
Copy link
Member Author

mathetake commented Jul 30, 2021

will do after the refactoring work here: proxy-wasm/proxy-wasm-cpp-host#183

@mathetake mathetake requested a review from lizan August 2, 2021 01:30
@mathetake
Copy link
Member Author

changed so we dispatch on main, rather than taking locks.

@PiotrSikora
Copy link
Contributor

Since the overall goal seems to be avoiding the envoy_ prefix in Wasm metrics, couldn't we automatically do that for all metrics defined in Wasm, instead of adding those implementation-specific hostcalls?

@mathetake
Copy link
Member Author

Since the overall goal seems to be avoiding the envoy_ prefix in Wasm metrics, couldn't we automatically do that for all metrics defined in Wasm, instead of adding those implementation-specific hostcalls?

ah that's good point and I think it's better UX. Let me rework.

@mathetake mathetake changed the title wasm: add foreign calls to un/register prometheus namespaces. wasm: register prometheus namespaces for Wasm plugin defined metrics. Aug 3, 2021
// Register the whole name if we couldn't find "_" in it.
[ns = stat_namespace.empty() ? std::string(name) : std::string(stat_namespace)]() -> void {
Server::PrometheusStatsFormatter::registerPrometheusNamespace(ns);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know enough about the current stats to know for sure, but isn't this too greedy? e.g. if someone defines cluster_foo metric in Wasm, wouldn't it automatically remove envoy_ prefix from all "native" metrics as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah that's true.. maybe better have something like "is_native" flag in Metric class, and prefix "envoy_" based on it, rather than using registerPrometheusNamespace?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that sounds good to me... although, it seems that such solution was discussed in #11808, but the prefix list was added instead. cc @lizan @mandarjog @ggreenway @jmarantz

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not familiar with wasm APIs at all, but could you require the plugin to register it's namespace, and clearly document that it should be specific to this plugin and not overlap with any existing native stat names, and that all plugin stats should be under that namespace? There's still the possibility of a plugin incorrectly registering for an incorrect prefix, but there's at least documentation about how to behave correctly to avoid such issues.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess my point is why do we have those "namespaces" in the first place, when in reality it's only about separating native Envoy metrics that append envoy_ prefix from those that don't?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry I'm on vacation but I noticed this.

Oh sorry to interrupt you, and thanks for taking your time.

If this is really specific to wasm then it seems unclean to put a bit in the general stats structure to handle a special case.

This bit, say "is_custom_metric" flag, will be only set by Wasm for now since afaik Wasn extension is the only extension which defines non-Envoy-native metrics dynamically. But in the future, maybe other extensions would have that ability to define custom metrics.

Copy link
Member Author

Choose a reason for hiding this comment

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

ping @jmarantz , wdyt ^^? Do you think the purpose is not worth a bit?

Copy link
Contributor

Choose a reason for hiding this comment

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

@mathetake I think that we should do it, using flags to differentiate between Envoy's internal and Wasm/Lua/whatever metrics is much better UX than the need to register and use Prometheus namespaces.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm fine with this.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK thank you all, I will rework this PR and add a "is_custom_metric" flag in Metric class to differentiate Envoy native metrics from others.

@lizan lizan added the waiting label Aug 12, 2021
@mathetake mathetake marked this pull request as draft August 23, 2021 14:18
@mathetake mathetake force-pushed the wasm-prometheus-namespace branch from e8b4a24 to a8536dc Compare August 23, 2021 14:58
@mathetake mathetake changed the title wasm: register prometheus namespaces for Wasm plugin defined metrics. stats: introduce is_custom_metric flag. Aug 23, 2021
test/per_file_coverage.sh Outdated Show resolved Hide resolved
@mathetake
Copy link
Member Author

mathetake commented Aug 24, 2021

@mathetake
Copy link
Member Author

anyway I believe this is ready for review.

@mathetake mathetake marked this pull request as ready for review August 24, 2021 00:41
@jmarantz
Copy link
Contributor

Sorry, one more thing: please refrain from force-pushing in Envoy github; that has the property of dropping review comments. I have never found it necessary to force-push in this workflow other than for fixing DCO.

@mathetake
Copy link
Member Author

mathetake commented Sep 10, 2021

sorry the one is actually for DCO - I used git revert xxx for reverting the DynamicName stuff (and pushed without realizing that would miss signed-off).

* return optional<view> for stripCustom...
* use StatNamePool instead of *Set
* add a TODO in prometheus_stats.cc for safer regex
* not use inlined CustomStatNamespaces in tests

Signed-off-by: Takeshi Yoneda <[email protected]>
@mathetake
Copy link
Member Author

mathetake commented Sep 10, 2021

How can we continue the dialog about getting a symbol-table-friendly way of making stats in wasm so we don't have catastrophic contention at scale?

I will open an issue for this! cc @PiotrSikora Do you want to say anything?

Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
jmarantz
jmarantz previously approved these changes Sep 10, 2021
Copy link
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

Looks great; couple of minor points and one concern around lifetime in your new StatName member var. But assuming at least the lifetime issue is commented on or just made safe by inspection, this is good from my end, and I'm ready for @mattklein123 to take another look.

source/extensions/common/wasm/wasm.cc Outdated Show resolved Hide resolved
source/server/admin/prometheus_stats.cc Outdated Show resolved Hide resolved
test/server/admin/prometheus_stats_test.cc Outdated Show resolved Hide resolved
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks for iterating on this!

@mattklein123 mattklein123 merged commit 0bbf23c into envoyproxy:main Sep 13, 2021
@mathetake mathetake deleted the wasm-prometheus-namespace branch September 13, 2021 23:30
@mathetake
Copy link
Member Author

Thank you so much for your reviews! @mattklein123 @jmarantz


#include "envoy/common/pure.h"

#include "absl/container/flat_hash_set.h"
Copy link
Member

Choose a reason for hiding this comment

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

unused here (only used in the impl)

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.

wasm: allow customization of prometheus namespaces
7 participants