Repository: envoyproxy/envoy
File: source/common/memory/stats.cc (C++)

Code before:
}

void Stats::dumpStatsToLog() {
#if defined(TCMALLOC)
  ENVOY_LOG_MISC(debug, "TCMalloc stats:\n{}", tcmalloc::MallocExtension::GetStats());
#elif defined(GPERFTOOLS_TCMALLOC)
  constexpr int buffer_size = 100000;
  auto buffer = std::make_unique<char[]>(buffer_size);
  MallocExtension::instance()->GetStats(buffer.get(), buffer_size);
  ENVOY_LOG_MISC(debug, "TCMalloc stats:\n{}", buffer.get());
#else
  return;
#endif
}

std::string Stats::dumpStats() {
#if defined(TCMALLOC)
  return tcmalloc::MallocExtension::GetStats();
#elif defined(GPERFTOOLS_TCMALLOC)
  constexpr int buffer_size = 100000;
  std::string buffer(buffer_size, '\0');
  MallocExtension::instance()->GetStats(buffer.data(), buffer_size);
  buffer.resize(strlen(buffer.c_str()));
  return buffer;
#else
  return "";
#endif
}

AllocatorManager::AllocatorManager(
    Api::Api& api, Envoy::Stats::Scope& scope,
    const envoy::config::bootstrap::v3::MemoryAllocatorManager& config)
    : bytes_to_release_(config.bytes_to_release()),
      memory_release_interval_msec_(std::chrono::milliseconds(
          PROTOBUF_GET_MS_OR_DEFAULT(config, memory_release_interval, 1000))),
      allocator_manager_stats_(MemoryAllocatorManagerStats{
          MEMORY_ALLOCATOR_MANAGER_STATS(POOL_COUNTER_PREFIX(scope, "tcmalloc."))}),
      api_(api) {
  configureBackgroundMemoryRelease();
};

AllocatorManager::~AllocatorManager() {
#if defined(TCMALLOC)
  if (tcmalloc_routine_dispatcher_) {
    tcmalloc_routine_dispatcher_->exit();
  }
  if (tcmalloc_thread_) {
    tcmalloc_thread_->join();
    tcmalloc_thread_.reset();
  }
#endif

Review comment (suggestion):
In this case, I think the admin endpoint should return 501 (Not implemented) and some text saying envoy wasn't built with tcmalloc.

Code after:
}

void Stats::dumpStatsToLog() {
#if defined(TCMALLOC)
  ENVOY_LOG_MISC(debug, "TCMalloc stats:\n{}", tcmalloc::MallocExtension::GetStats());
#elif defined(GPERFTOOLS_TCMALLOC)
  constexpr int buffer_size = 100000;
  auto buffer = std::make_unique<char[]>(buffer_size);
  MallocExtension::instance()->GetStats(buffer.get(), buffer_size);
  ENVOY_LOG_MISC(debug, "TCMalloc stats:\n{}", buffer.get());
#else
  return;
#endif
}

absl::optional<std::string> Stats::dumpStats() {
#if defined(TCMALLOC)
  return tcmalloc::MallocExtension::GetStats();
#elif defined(GPERFTOOLS_TCMALLOC)
  constexpr int buffer_size = 100000;
  std::string buffer(buffer_size, '\0');
  MallocExtension::instance()->GetStats(buffer.data(), buffer_size);
  buffer.resize(strlen(buffer.c_str()));
  return buffer;
#else
  return absl::nullopt;
#endif
}

AllocatorManager::AllocatorManager(
    Api::Api& api, Envoy::Stats::Scope& scope,
    const envoy::config::bootstrap::v3::MemoryAllocatorManager& config)
    : bytes_to_release_(config.bytes_to_release()),
      memory_release_interval_msec_(std::chrono::milliseconds(
          PROTOBUF_GET_MS_OR_DEFAULT(config, memory_release_interval, 1000))),
      allocator_manager_stats_(MemoryAllocatorManagerStats{
          MEMORY_ALLOCATOR_MANAGER_STATS(POOL_COUNTER_PREFIX(scope, "tcmalloc."))}),
      api_(api) {
  configureBackgroundMemoryRelease();
};

AllocatorManager::~AllocatorManager() {
#if defined(TCMALLOC)
  if (tcmalloc_routine_dispatcher_) {
    tcmalloc_routine_dispatcher_->exit();
  }
  if (tcmalloc_thread_) {
    tcmalloc_thread_->join();
    tcmalloc_thread_.reset();
  }
#endif