Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
15 changes: 6 additions & 9 deletions source/common/common/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,27 +282,24 @@ template <Id id> class Loggable {

} // namespace Logger

// Convert the line macro to a string literal for concatenation in log macros.
#define DO_STRINGIZE(x) STRINGIZE(x)
#define STRINGIZE(x) #x
#define LINE_STRING DO_STRINGIZE(__LINE__)
#define LOG_PREFIX "[" __FILE__ ":" LINE_STRING "] "

/**
* Base logging macros. It is expected that users will use the convenience macros below rather than
* invoke these directly.
*/

#define ENVOY_LOG_COMP_LEVEL(LOGGER, LEVEL) \
(static_cast<spdlog::level::level_enum>(Envoy::Logger::Logger::LEVEL) >= LOGGER.level())
#define ENVOY_SPDLOG_LEVEL(LEVEL) \
(static_cast<spdlog::level::level_enum>(Envoy::Logger::Logger::LEVEL))

#define ENVOY_LOG_COMP_LEVEL(LOGGER, LEVEL) (ENVOY_SPDLOG_LEVEL(LEVEL) >= LOGGER.level())

// Compare levels before invoking logger. This is an optimization to avoid
// executing expressions computing log contents when they would be suppressed.
// The same filtering will also occur in spdlog::logger.
#define ENVOY_LOG_COMP_AND_LOG(LOGGER, LEVEL, ...) \
do { \
if (ENVOY_LOG_COMP_LEVEL(LOGGER, LEVEL)) { \
LOGGER.LEVEL(LOG_PREFIX __VA_ARGS__); \
LOGGER.log(::spdlog::source_loc{__FILE__, __LINE__, __func__}, ENVOY_SPDLOG_LEVEL(LEVEL), \
__VA_ARGS__); \
} \
} while (0)

Expand Down
25 changes: 24 additions & 1 deletion source/server/options_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@

namespace Envoy {
namespace {
std::string prefixLogFormatWithLocation(const std::string& log_format) {
Comment thread
ggreenway marked this conversation as resolved.
Outdated
std::string result;
for (size_t i = 0; i < log_format.size(); ++i) {
if (i + 1 < log_format.size() && log_format[i] == '%') {
if (log_format[i + 1] == 'v') {
result += "[%g:%#] ";
}
// Print '%' and go directly to the next character.
result += '%';
i++;
}
result += log_format[i];
}
return result;
}

std::vector<std::string> toArgsVector(int argc, const char* const* argv) {
std::vector<std::string> args;
args.reserve(argc);
Expand Down Expand Up @@ -92,6 +108,9 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args,
TCLAP::SwitchArg log_format_escaped("", "log-format-escaped",
"Escape c-style escape sequences in the application logs",
cmd, false);
TCLAP::ValueArg<bool> log_format_prefix_with_location(
Comment thread
ggreenway marked this conversation as resolved.
"", "log-format-prefix-with-location",
"Prefix all logged messages with '[path/to/file.cc:99] '.", false, true, "bool", cmd);
Comment thread
ggreenway marked this conversation as resolved.
Outdated
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 @@ -167,7 +186,11 @@ OptionsImpl::OptionsImpl(std::vector<std::string> args,
log_level_ = default_log_level;
}

log_format_ = log_format.getValue();
if (log_format_prefix_with_location.getValue()) {
log_format_ = prefixLogFormatWithLocation(log_format.getValue());
} else {
log_format_ = log_format.getValue();
}
log_format_escaped_ = log_format_escaped.getValue();

parseComponentLogLevels(component_log_level.getValue());
Expand Down
34 changes: 32 additions & 2 deletions test/server/options_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ class OptionsImplTest : public testing::Test {
return std::make_unique<OptionsImpl>(
std::move(words), [](bool) { return "1"; }, spdlog::level::warn);
}

std::unique_ptr<OptionsImpl> createOptionsImpl(std::vector<std::string> args) {
return std::make_unique<OptionsImpl>(
std::move(args), [](bool) { return "1"; }, spdlog::level::warn);
}
};

TEST_F(OptionsImplTest, HotRestartVersion) {
Expand Down Expand Up @@ -89,7 +94,7 @@ TEST_F(OptionsImplTest, All) {
EXPECT_EQ(1U, options->restartEpoch());
EXPECT_EQ(spdlog::level::info, options->logLevel());
EXPECT_EQ(2, options->componentLogLevels().size());
EXPECT_EQ("[%v]", options->logFormat());
EXPECT_EQ("[[%g:%#] %v]", options->logFormat());
EXPECT_EQ("/foo/bar", options->logPath());
EXPECT_EQ("cluster", options->serviceClusterName());
EXPECT_EQ("node", options->serviceNodeName());
Expand Down Expand Up @@ -255,7 +260,8 @@ TEST_F(OptionsImplTest, OptionsAreInSyncWithProto) {
// 4. allow-unknown-fields - deprecated alias of allow-unknown-static-fields.
// 5. use-fake-symbol-table - short-term override for rollout of real symbol-table implementation.
// 6. hot restart version - print the hot restart version and exit.
EXPECT_EQ(options->count() - 6, command_line_options->GetDescriptor()->field_count());
// 7. log-format-prefix-with-location - short-term override for rollout of dynamic log format.
EXPECT_EQ(options->count() - 7, command_line_options->GetDescriptor()->field_count());
}

TEST_F(OptionsImplTest, OptionsFromArgv) {
Expand Down Expand Up @@ -400,6 +406,30 @@ TEST_F(OptionsImplTest, SetCpusetOnly) {
EXPECT_NE(options->concurrency(), 0);
}

TEST_F(OptionsImplTest, LogFormatDefault) {
std::unique_ptr<OptionsImpl> options = createOptionsImpl({"envoy", "-c", "hello"});
EXPECT_EQ(options->logFormat(), "[%Y-%m-%d %T.%e][%t][%l][%n] [%g:%#] %v");
}

TEST_F(OptionsImplTest, LogFormatDefaultNoPrefix) {
std::unique_ptr<OptionsImpl> options =
createOptionsImpl({"envoy", "-c", "hello", "--log-format-prefix-with-location", "0"});
EXPECT_EQ(options->logFormat(), "[%Y-%m-%d %T.%e][%t][%l][%n] %v");
}

TEST_F(OptionsImplTest, LogFormatOverride) {
std::unique_ptr<OptionsImpl> options =
createOptionsImpl({"envoy", "-c", "hello", "--log-format", "%%v %v %t %v"});
EXPECT_EQ(options->logFormat(), "%%v [%g:%#] %v %t [%g:%#] %v");
}

TEST_F(OptionsImplTest, LogFormatOverrideNoPrefix) {
std::unique_ptr<OptionsImpl> options =
createOptionsImpl({"envoy", "-c", "hello", "--log-format", "%%v %v %t %v",
"--log-format-prefix-with-location 0"});
EXPECT_EQ(options->logFormat(), "%%v %v %t %v");
}

#if defined(__linux__)

using testing::DoAll;
Expand Down