Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/envoy/admin/v3/server_info.proto
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ message CommandLineOptions {
// See :option:`--enable-fine-grain-logging` for details.
bool enable_fine_grain_logging = 34;

// See :option:`--fine-grain-log-levels` for details.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it require --enable-fine-grain-logging to work?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I see that the code below requires that. nvm.

string fine_grain_log_levels = 43;

// See :option:`--socket-path` for details.
string socket_path = 35;

Expand Down
7 changes: 7 additions & 0 deletions envoy/server/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ class Options {
*/
virtual bool enableFineGrainLogging() const PURE;

/**
* @return const std::vector<std::pair<std::string, spdlog::level::level_enum>>& pair of
* glob-pattern,log-level for all configured fine-grain log overrides.
*/
virtual const std::vector<std::pair<std::string, spdlog::level::level_enum>>&
fineGrainLogLevels() const PURE;

/**
* @return const std::string& the log file path.
*/
Expand Down
1 change: 1 addition & 0 deletions source/exe/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ envoy_cc_library(
":stripped_main_base_lib",
"//source/common/api:os_sys_calls_lib",
"//source/common/common:compiler_requirements_lib",
"//source/common/common:minimal_logger_lib",
"//source/common/common:perf_annotation_lib",
"//source/common/grpc:google_grpc_context_lib",
"//source/server:hot_restart_lib",
Expand Down
9 changes: 9 additions & 0 deletions source/exe/main_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "envoy/config/listener/v3/listener.pb.h"

#include "source/common/common/compiler_requirements.h"
#include "source/common/common/fine_grain_logger.h"
#include "source/common/common/logger.h"
#include "source/common/common/perf_annotation.h"
#include "source/common/common/thread.h"
Expand Down Expand Up @@ -70,6 +71,14 @@ MainCommonBase::MainCommonBase(const Server::Options& options, Event::TimeSystem
logging_context_ = std::make_unique<Logger::Context>(
options_.logLevel(), options_.logFormat(), restarter_->logLock(), options_.logFormatEscaped(),
options_.mode() == Server::Mode::Validate ? false : options_.enableFineGrainLogging());
if (options_.enableFineGrainLogging() && !options_.fineGrainLogLevels().empty()) {
std::vector<std::pair<absl::string_view, int>> glob_levels;
glob_levels.reserve(options_.fineGrainLogLevels().size());
for (const auto& [glob, level] : options_.fineGrainLogLevels()) {
glob_levels.emplace_back(glob, static_cast<int>(level));
}
getFineGrainLogContext().updateVerbositySetting(glob_levels);
}
init(time_system, listener_hooks, std::move(random_generator), std::move(process_context),
createFunction());
}
Expand Down
1 change: 1 addition & 0 deletions source/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ envoy_cc_library(
"//source/common/stats:stats_lib",
"//source/common/stats:tag_utility_lib",
"//source/common/version:version_lib",
"@abseil-cpp//absl/strings",
"@envoy_api//envoy/admin/v3:pkg_cc_proto",
"@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto",
"@tclap",
Expand Down
42 changes: 42 additions & 0 deletions source/server/options_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "source/server/options_impl_platform.h"

#include "absl/strings/str_replace.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "spdlog/spdlog.h"
Expand Down Expand Up @@ -49,6 +50,11 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args,

const std::string component_log_level_string =
"Comma-separated list of component log levels. For example upstream:debug,config:trace";
const std::string fine_grain_log_levels_string =
"Comma-separated list of file-level log overrides for fine-grain logging. "
"Glob patterns are matched against source file names. For example "
"\"*filter*:debug,source/common/common/*:trace\". "
"Requires --enable-fine-grain-logging.";
const std::string log_format_string =
fmt::format("Log message format in spdlog syntax "
"(see https://github.com/gabime/spdlog/wiki/3.-Custom-formatting)"
Expand Down Expand Up @@ -123,6 +129,8 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args,
TCLAP::SwitchArg enable_fine_grain_logging(
"", "enable-fine-grain-logging",
"Logger mode: enable file level log control (Fine-Grain Logger) or not", cmd, false);
TCLAP::ValueArg<std::string> fine_grain_log_levels(
"", "fine-grain-log-levels", fine_grain_log_levels_string, false, "", "string", cmd);
TCLAP::ValueArg<std::string> log_path("", "log-path", "Path to logfile", false, "", "string",
cmd);
TCLAP::ValueArg<uint32_t> restart_epoch("", "restart-epoch", "Hot restart epoch #", false, 0,
Expand Down Expand Up @@ -228,7 +236,13 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args,
"error: --component-log-level will not work with --enable-fine-grain-logging");
}

if (!fine_grain_log_levels.getValue().empty() && !enable_fine_grain_logging_) {
throw MalformedArgvException(
"error: --fine-grain-log-levels requires --enable-fine-grain-logging");
}

parseComponentLogLevels(component_log_level.getValue());
parseFineGrainLogLevels(fine_grain_log_levels.getValue());

if (mode.getValue() == "serve") {
mode_ = Server::Mode::Serve;
Expand Down Expand Up @@ -397,6 +411,26 @@ void OptionsImpl::parseComponentLogLevels(const std::string& component_log_level

void OptionsImpl::logError(const std::string& error) { throw MalformedArgvException(error); }

void OptionsImpl::parseFineGrainLogLevels(const std::string& fine_grain_log_levels) {
if (fine_grain_log_levels.empty()) {
return;
}
std::vector<std::string> log_levels = absl::StrSplit(fine_grain_log_levels, ',');
for (auto& level : log_levels) {
std::vector<std::string> glob_level = absl::StrSplit(level, absl::MaxSplits(':', 1));
if (glob_level.size() != 2) {
logError(
fmt::format("error: fine-grain log level not correctly specified '{}'", level));
}
const std::string glob = glob_level[0];
auto status_or_error = parseAndValidateLogLevel(glob_level[1]);
if (!status_or_error.status().ok()) {
logError(std::string(status_or_error.status().message()));
}
fine_grain_log_levels_.push_back(std::make_pair(glob, status_or_error.value()));
}
}

Server::CommandLineOptionsPtr OptionsImpl::toCommandLineOptions() const {
Server::CommandLineOptionsPtr command_line_options =
std::make_unique<envoy::admin::v3::CommandLineOptions>();
Expand All @@ -419,6 +453,14 @@ Server::CommandLineOptionsPtr OptionsImpl::toCommandLineOptions() const {
command_line_options->set_log_format(logFormat());
command_line_options->set_log_format_escaped(logFormatEscaped());
command_line_options->set_enable_fine_grain_logging(enableFineGrainLogging());
if (!fine_grain_log_levels_.empty()) {
std::vector<std::string> parts;
parts.reserve(fine_grain_log_levels_.size());
for (const auto& [glob, level] : fine_grain_log_levels_) {
parts.push_back(fmt::format("{}:{}", glob, spdlog::level::to_string_view(level)));
}
command_line_options->set_fine_grain_log_levels(absl::StrJoin(parts, ","));
}
command_line_options->set_log_path(logPath());
command_line_options->set_service_cluster(serviceClusterName());
command_line_options->set_service_node(serviceNodeName());
Expand Down
1 change: 1 addition & 0 deletions source/server/options_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class OptionsImpl : public OptionsImplBase {

Server::CommandLineOptionsPtr toCommandLineOptions() const override;
void parseComponentLogLevels(const std::string& component_log_levels);
void parseFineGrainLogLevels(const std::string& fine_grain_log_levels);
static void logError(const std::string& error);
static std::string allowedLogLevels();
};
Expand Down
5 changes: 5 additions & 0 deletions source/server/options_impl_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ class OptionsImplBase : public Server::Options, protected Logger::Loggable<Logge
bool logFormatSet() const override { return log_format_set_; }
bool logFormatEscaped() const override { return log_format_escaped_; }
bool enableFineGrainLogging() const override { return enable_fine_grain_logging_; }
const std::vector<std::pair<std::string, spdlog::level::level_enum>>&
fineGrainLogLevels() const override {
return fine_grain_log_levels_;
}
const std::string& logPath() const override { return log_path_; }
uint64_t restartEpoch() const override { return restart_epoch_; }
Server::Mode mode() const override { return mode_; }
Expand Down Expand Up @@ -199,6 +203,7 @@ class OptionsImplBase : public Server::Options, protected Logger::Loggable<Logge
spdlog::level::level_enum log_level_{spdlog::level::info};
std::vector<std::pair<std::string, spdlog::level::level_enum>> component_log_levels_;
std::string component_log_level_str_;
std::vector<std::pair<std::string, spdlog::level::level_enum>> fine_grain_log_levels_;
std::string log_format_{Logger::Logger::DEFAULT_LOG_FORMAT};
bool log_format_set_{false};
bool log_format_escaped_{false};
Expand Down
2 changes: 2 additions & 0 deletions test/mocks/server/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class MockOptions : public Options {
MOCK_METHOD(bool, logFormatSet, (), (const));
MOCK_METHOD(bool, logFormatEscaped, (), (const));
MOCK_METHOD(bool, enableFineGrainLogging, (), (const));
MOCK_METHOD((const std::vector<std::pair<std::string, spdlog::level::level_enum>>&),
fineGrainLogLevels, (), (const));
MOCK_METHOD(const std::string&, logPath, (), (const));
MOCK_METHOD(uint64_t, restartEpoch, (), (const));
MOCK_METHOD(std::chrono::milliseconds, fileFlushIntervalMsec, (), (const));
Expand Down
31 changes: 31 additions & 0 deletions test/server/options_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,37 @@ TEST_F(OptionsImplTest, SetEnableFineGrainLogging) {
EXPECT_TRUE(options->enableFineGrainLogging());
}

TEST_F(OptionsImplTest, FineGrainLogLevelsCLI) {
std::unique_ptr<OptionsImpl> options = createOptionsImpl(
"envoy --enable-fine-grain-logging --fine-grain-log-levels *filter*:debug,*common*:trace");
EXPECT_TRUE(options->enableFineGrainLogging());
const auto& levels = options->fineGrainLogLevels();
ASSERT_EQ(2, levels.size());
EXPECT_EQ("*filter*", levels[0].first);
EXPECT_EQ(spdlog::level::debug, levels[0].second);
EXPECT_EQ("*common*", levels[1].first);
EXPECT_EQ(spdlog::level::trace, levels[1].second);
}

TEST_F(OptionsImplTest, FineGrainLogLevelsRequiresFineGrainLogging) {
EXPECT_THROW_WITH_REGEX(
createOptionsImpl("envoy --fine-grain-log-levels *filter*:debug"), MalformedArgvException,
"error: --fine-grain-log-levels requires --enable-fine-grain-logging");
}

TEST_F(OptionsImplTest, InvalidFineGrainLogLevel) {
std::unique_ptr<OptionsImpl> options = createOptionsImpl("envoy --mode init_only");
EXPECT_THROW_WITH_REGEX(options->parseFineGrainLogLevels("*filter*:blah"),
MalformedArgvException, "error: invalid log level specified 'blah'");
}

TEST_F(OptionsImplTest, InvalidFineGrainLogLevelStructure) {
std::unique_ptr<OptionsImpl> options = createOptionsImpl("envoy --mode init_only");
EXPECT_THROW_WITH_REGEX(options->parseFineGrainLogLevels("*filter*"),
MalformedArgvException,
"error: fine-grain log level not correctly specified '\\*filter\\*'");
}

// Validates that the server_info proto is in sync with the options.
TEST_F(OptionsImplTest, OptionsAreInSyncWithProto) {
std::unique_ptr<OptionsImpl> options = createOptionsImpl("envoy -c hello");
Expand Down