diff --git a/source/common/http/http2/BUILD b/source/common/http/http2/BUILD index 653760f489b74..f1c9fefbc9c53 100644 --- a/source/common/http/http2/BUILD +++ b/source/common/http/http2/BUILD @@ -65,6 +65,18 @@ envoy_cc_library( ], ) +# Separate library for some nghttp2 setup stuff to avoid having tests take a +# dependency on everything in codec_lib. +envoy_cc_library( + name = "nghttp2_lib", + srcs = ["nghttp2.cc"], + hdrs = ["nghttp2.h"], + external_deps = ["nghttp2"], + deps = [ + "//source/common/common:minimal_logger_lib", + ], +) + envoy_cc_library( name = "conn_pool_lib", srcs = ["conn_pool.cc"], diff --git a/source/common/http/http2/nghttp2.cc b/source/common/http/http2/nghttp2.cc new file mode 100644 index 0000000000000..2c415c584e0b3 --- /dev/null +++ b/source/common/http/http2/nghttp2.cc @@ -0,0 +1,35 @@ +#include "source/common/http/http2/nghttp2.h" + +#include "source/common/common/logger.h" + +// nghttp2 fails to convey the POSIX ssize_t declaration +// that Microsoft declines to implement. Pick up a valid +// ssize_t declaration for win32 in our platform.h +#include "envoy/common/platform.h" + +#include "nghttp2/nghttp2.h" + +namespace Envoy { +namespace Http { +namespace Http2 { + +void initializeNghttp2Logging() { + // When ENVOY_NGHTTP2_TRACE is set, we install a debug logger, to prevent nghttp2 + // logging directly to stdout at -l trace. + nghttp2_set_debug_vprintf_callback([](const char* format, va_list args) { + if (std::getenv("ENVOY_NGHTTP2_TRACE") != nullptr) { + char buf[2048]; + const int n = ::vsnprintf(buf, sizeof(buf), format, args); + // nghttp2 inserts new lines, but we also insert a new line in the ENVOY_LOG + // below, so avoid double \n. + if (n >= 1 && static_cast(n) < sizeof(buf) && buf[n - 1] == '\n') { + buf[n - 1] = '\0'; + } + ENVOY_LOG_TO_LOGGER(Logger::Registry::getLog(Logger::Id::http2), trace, "nghttp2: {}", buf); + } + }); +} + +} // namespace Http2 +} // namespace Http +} // namespace Envoy diff --git a/source/common/http/http2/nghttp2.h b/source/common/http/http2/nghttp2.h new file mode 100644 index 0000000000000..3a19e6ba3c570 --- /dev/null +++ b/source/common/http/http2/nghttp2.h @@ -0,0 +1,14 @@ +#pragma once + +namespace Envoy { +namespace Http { +namespace Http2 { + +/** + * Setup nghttp2 trace-level logging for when debugging. + */ +void initializeNghttp2Logging(); + +} // namespace Http2 +} // namespace Http +} // namespace Envoy diff --git a/source/exe/BUILD b/source/exe/BUILD index 59246022ad089..bfdef77fcb57e 100644 --- a/source/exe/BUILD +++ b/source/exe/BUILD @@ -215,6 +215,7 @@ envoy_cc_library( deps = [ "//source/common/common:assert_lib", "//source/common/event:libevent_lib", + "//source/common/http/http2:nghttp2_lib", "//source/common/network/dns_resolver:dns_factory_util_lib", "//source/server:proto_descriptors_lib", ], diff --git a/source/exe/process_wide.cc b/source/exe/process_wide.cc index d6fea6ccce0f0..dca2fc0da9ae1 100644 --- a/source/exe/process_wide.cc +++ b/source/exe/process_wide.cc @@ -4,6 +4,7 @@ #include "source/common/common/assert.h" #include "source/common/event/libevent.h" +#include "source/common/http/http2/nghttp2.h" #include "source/server/proto_descriptors.h" namespace Envoy { @@ -37,6 +38,7 @@ ProcessWide::ProcessWide(bool validate_proto_descriptors) { #else UNREFERENCED_PARAMETER(validate_proto_descriptors); #endif + Http::Http2::initializeNghttp2Logging(); // We do not initialize Google gRPC here -- we instead instantiate // Grpc::GoogleGrpcContext in MainCommon immediately after instantiating diff --git a/test/per_file_coverage.sh b/test/per_file_coverage.sh index a04977cd3946b..3685a28f0e2f0 100755 --- a/test/per_file_coverage.sh +++ b/test/per_file_coverage.sh @@ -10,7 +10,7 @@ declare -a KNOWN_LOW_COVERAGE=( "source/common/crypto:95.5" "source/common/event:95.1" # Emulated edge events guards don't report LCOV "source/common/filesystem/posix:96.2" # FileReadToEndNotReadable fails in some env; createPath can't test all failure branches. -"source/common/http/http2:96.0" +"source/common/http/http2:95.9" "source/common/json:94.6" "source/common/matcher:94.4" "source/common/memory:73.6" # tcmalloc code path is not enabled in coverage build, only gperf tcmalloc, see PR#32589