-
Notifications
You must be signed in to change notification settings - Fork 5.5k
stats: Add universal stats tag from CLI #18668
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
Changes from 12 commits
44bc363
fe4dc28
47213a7
01af8ae
36f26c7
6593ad3
3786950
08fe30b
da5398b
7db7ea5
4f0dd6f
2db3169
76a51de
0511d8a
9185f89
b50bef6
1fd046a
1c12312
efd3b5a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,8 @@ | ||
| #include "source/common/stats/tag_utility.h" | ||
|
|
||
| #include <regex> | ||
|
|
||
| #include "source/common/config/well_known_names.h" | ||
| #include "source/common/stats/symbol_table_impl.h" | ||
|
|
||
| namespace Envoy { | ||
|
|
@@ -48,6 +51,29 @@ SymbolTable::StoragePtr TagStatNameJoiner::joinNameAndTags(StatName name, | |
|
|
||
| return symbol_table.join(stat_names); | ||
| } | ||
|
|
||
| bool isTagValueValid(absl::string_view name) { | ||
| std::regex regex{Config::NAME_REGEX, std::regex::optimize}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the existing code, NAME_REGEX is evaluated by RE2, not std::regex, so if you want consistency you should. use RE2 to test it. |
||
| int cntr = 0; | ||
| for (auto i = std::regex_iterator<absl::string_view::iterator>(name.begin(), name.end(), regex); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rather than iterating I'd just use a regex with begin/end anchors. |
||
| i != std::regex_iterator<absl::string_view::iterator>(); ++i) { | ||
| cntr++; | ||
| if (cntr > 1) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool isTagNameValid(absl::string_view value) { | ||
| for (const auto& token : value) { | ||
| if (!absl::ascii_isalnum(token)) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| } // namespace TagUtility | ||
| } // namespace Stats | ||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| #include "source/common/common/logger.h" | ||
| #include "source/common/common/macros.h" | ||
| #include "source/common/protobuf/utility.h" | ||
| #include "source/common/stats/tag_utility.h" | ||
| #include "source/common/version/version.h" | ||
| #include "source/server/options_impl_platform.h" | ||
|
|
||
|
|
@@ -151,6 +152,14 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args, | |
| "600", "string", cmd); | ||
| TCLAP::SwitchArg enable_core_dump("", "enable-core-dump", "Enable core dumps", cmd, false); | ||
|
|
||
| TCLAP::MultiArg<std::string> stats_tag( | ||
| "", "stats-tag", | ||
| "This flag provides a universal tag for all stats generated by Envoy. The format is " | ||
| "``tag:value``. Only alphanumeric values are allowed for tag names. For tag values all " | ||
| "characters are permitted except for '.' (dot). This flag can be repeated multiple times to " | ||
| "set multiple universal tags. However, multiple stats with different values are not allowed.", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this is enough to establish the "envoy standard" but let's make sure @ggreenway and @snowp buy into this syntax. I wasn't sure what you meant by the last sentence. Did you mean "multiple values for the same tag name are not allowed"? |
||
| false, "string", cmd); | ||
|
|
||
| cmd.setExceptionHandling(false); | ||
| TRY_ASSERT_MAIN_THREAD { | ||
| cmd.parse(args); | ||
|
|
@@ -282,6 +291,33 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args, | |
| if (!disable_extensions.getValue().empty()) { | ||
| disabled_extensions_ = absl::StrSplit(disable_extensions.getValue(), ','); | ||
| } | ||
|
|
||
| if (!stats_tag.getValue().empty()) { | ||
| for (const auto& cli_tag_pair : stats_tag.getValue()) { | ||
|
|
||
| absl::string_view::size_type colon = cli_tag_pair.find(':'); | ||
|
davinci26 marked this conversation as resolved.
Outdated
|
||
| if (colon == absl::string_view::npos) { | ||
| throw MalformedArgvException( | ||
| fmt::format("error: misformatted stats-tag '{}'", cli_tag_pair)); | ||
| } | ||
|
|
||
| auto name = cli_tag_pair.substr(0, colon); | ||
| if (!Stats::TagUtility::isTagNameValid(name)) { | ||
| throw MalformedArgvException( | ||
| fmt::format("error: misformatted stats-tag '{}' contains invalid char in '{}'", | ||
| cli_tag_pair, name)); | ||
| } | ||
|
|
||
| auto value = cli_tag_pair.substr(colon + 1); | ||
| if (!Stats::TagUtility::isTagValueValid(value)) { | ||
| throw MalformedArgvException( | ||
| fmt::format("error: misformatted stats-tag '{}' contains invalid char in '{}'", | ||
| cli_tag_pair, value)); | ||
| } | ||
|
|
||
| stats_tags_.emplace_back(Stats::Tag{std::string(name), std::string(value)}); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| spdlog::level::level_enum OptionsImpl::parseAndValidateLogLevel(absl::string_view log_level) { | ||
|
|
@@ -396,6 +432,9 @@ Server::CommandLineOptionsPtr OptionsImpl::toCommandLineOptions() const { | |
| } | ||
| command_line_options->set_socket_path(socketPath()); | ||
| command_line_options->set_socket_mode(socketMode()); | ||
| for (const auto& tag : statsTags()) { | ||
| command_line_options->add_stats_tag(fmt::format("{}:{}", tag.name_, tag.value_)); | ||
| } | ||
| return command_line_options; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.