diff --git a/source/server/BUILD b/source/server/BUILD index 59e846788cef3..e1ac3844964e9 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -12,6 +12,7 @@ envoy_package() envoy_cc_library( name = "backtrace_lib", + srcs = ["backtrace.cc"], hdrs = ["backtrace.h"], external_deps = [ "abseil_stacktrace", diff --git a/source/server/backtrace.cc b/source/server/backtrace.cc new file mode 100644 index 0000000000000..46ca057ee8a96 --- /dev/null +++ b/source/server/backtrace.cc @@ -0,0 +1,11 @@ +#include "server/backtrace.h" + +#include + +namespace Envoy { + +bool BackwardsTrace::log_to_stderr_ = false; + +void BackwardsTrace::setLogToStderr(bool log_to_stderr) { log_to_stderr_ = log_to_stderr; } + +} // namespace Envoy diff --git a/source/server/backtrace.h b/source/server/backtrace.h index ff28d018046ec..966d9017baf26 100644 --- a/source/server/backtrace.h +++ b/source/server/backtrace.h @@ -38,6 +38,22 @@ class BackwardsTrace : Logger::Loggable { public: BackwardsTrace() = default; + /** + * Directs the output of logTrace() to directly stderr rather than the + * logging infrastructure. + * + * This is intended for coverage tests, where we enable trace logs, but send + * them to /dev/null to avoid accumulating too much data in CI. + * + * @param log_to_stderr Whether to log to stderr or the logging system. + */ + static void setLogToStderr(bool log_to_stderr); + + /** + * @return whether the system directing backtraces directly to stderr. + */ + static bool logToStderr() { return log_to_stderr_; } + /** * Capture a stack trace. * @@ -67,6 +83,11 @@ class BackwardsTrace : Logger::Loggable { * Log the stack trace. */ void logTrace() { + if (log_to_stderr_) { + printTrace(std::cerr); + return; + } + ENVOY_LOG(critical, "Backtrace (use tools/stack_decode.py to get line numbers):"); ENVOY_LOG(critical, "Envoy version: {}", VersionInfo::version()); @@ -94,6 +115,8 @@ class BackwardsTrace : Logger::Loggable { } private: + static bool log_to_stderr_; + /** * Visit the previously captured stack trace. * diff --git a/test/BUILD b/test/BUILD index 0c9065472631e..41cf8c14bcb36 100644 --- a/test/BUILD +++ b/test/BUILD @@ -31,6 +31,7 @@ envoy_cc_test_library( "//source/common/common:thread_lib", "//source/common/event:libevent_lib", "//source/exe:process_wide_lib", + "//source/server:backtrace_lib", "//test/common/runtime:utility_lib", "//test/mocks/access_log:access_log_mocks", "//test/test_common:environment_lib", diff --git a/test/server/backtrace_test.cc b/test/server/backtrace_test.cc index 91151f5b515c7..a83ae4d9a4099 100644 --- a/test/server/backtrace_test.cc +++ b/test/server/backtrace_test.cc @@ -9,9 +9,12 @@ TEST(Backward, Basic) { // There isn't much to test here and this feature is really just useful for // debugging. This test simply verifies that we do not cause a crash when // logging a backtrace, and covers the added lines. + const bool save_log_to_stderr = BackwardsTrace::logToStderr(); + BackwardsTrace::setLogToStderr(false); BackwardsTrace tracer; tracer.capture(); EXPECT_LOG_CONTAINS("critical", "Envoy version:", tracer.logTrace()); + BackwardsTrace::setLogToStderr(save_log_to_stderr); } TEST(Backward, InvalidUsageTest) { diff --git a/test/test_runner.cc b/test/test_runner.cc index d04ea695ed97a..5eedad5ae23f6 100644 --- a/test/test_runner.cc +++ b/test/test_runner.cc @@ -10,6 +10,8 @@ #include "exe/process_wide.h" +#include "server/backtrace.h" + #include "test/common/runtime/utility.h" #include "test/mocks/access_log/mocks.h" #include "test/test_common/environment.h" @@ -103,10 +105,22 @@ int TestRunner::RunTests(int argc, char** argv) { listeners.Append(new RuntimeManagingListener(runtime_override)); } +#ifdef ENVOY_CONFIG_COVERAGE + // Coverage tests are run with -l trace --log-path /dev/null, in order to + // ensure that all of the code-paths from the maximum level of tracing are + // covered in tests, but we don't wind up filling up CI with useless detailed + // artifacts. + // + // The downside of this is that if there's a crash, the backtrace is lost, as + // the backtracing mechanism uses logging, so force the backtraces to stderr. + BackwardsTrace::setLogToStderr(true); +#endif + TestEnvironment::initializeOptions(argc, argv); Thread::MutexBasicLockable lock; - Logger::Context logging_state(TestEnvironment::getOptions().logLevel(), - TestEnvironment::getOptions().logFormat(), lock, false); + + Server::Options& options = TestEnvironment::getOptions(); + Logger::Context logging_state(options.logLevel(), options.logFormat(), lock, false); // Allocate fake log access manager. testing::NiceMock access_log_manager; diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index 24ba7e79890ca..4990223faaec9 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -385,6 +385,8 @@ backgrounded backoff backpressure backticks +backtraces +backtracing balancer balancers barbaz