From 147c66d67ce83778fc3f102dd132ec095e6032fc Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 12 May 2021 09:46:49 -0400
Subject: [PATCH] SL-10297: Simplify implementation of
 LLSingletonBase::logwarns() etc.

Introduce 'string_params' typedef for std::initialization_list<std::string>,
and make logwarns(), loginfos(), logdebugs() and logerrs() accept const
string_params&.

Eliminate the central log() function in llsingleton.cpp that used LL_VLOGS().
To cache the result of a (moderately expensive) Log::shouldLog() call,
LL_VLOGS() wants its CallSite object to be static -- but of course the
shouldLog() result will differ for different ELevel values, so LL_VLOGS()
instantiates a static array of CallSite instances. It seems silly to funnel
distinct logwarns(), etc., functions through a common log() function only to
have LL_VLOGS() tease apart ELevel values again. Instead, make logwarns()
directly invoke LL_WARNS(), and similarly for the rest.

To reduce boilerplate in these distinct functions, teach std::ostream how to
stream a string_params instance by looping over its elements. Then each
logwarns(), etc., function can simply stream its string_params argument to
LL_WARNS() or whichever.

In particular, eliminate the LLERROR_CRASH macro in logerrs(). The fact that
it invokes LL_ERRS() ensures that its LL_ENDL macro will crash the viewer.
---
 indra/llcommon/llsingleton.cpp | 37 ++++++++++++++--------------------
 indra/llcommon/llsingleton.h   | 11 ++++++----
 2 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index 4b1666563e0..6b1986d0e91 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -38,10 +38,6 @@
 #include <sstream>
 #include <stdexcept>
 
-namespace {
-void log(LLError::ELevel level, std::initializer_list<std::string_view>);
-} // anonymous namespace
-
 // Our master list of all LLSingletons is itself an LLSingleton. We used to
 // store it in a function-local static, but that could get destroyed before
 // the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to
@@ -450,43 +446,40 @@ void LLSingletonBase::deleteAll()
 /*---------------------------- Logging helpers -----------------------------*/
 namespace {
 
-void log(LLError::ELevel level, std::initializer_list<std::string_view> args)
+std::ostream& operator<<(std::ostream& out, const LLSingletonBase::string_params& args)
 {
-    LL_VLOGS(level, "LLSingleton");
-        for (auto arg : args)
-        {
-            LL_CONT << arg;
-        }
-    LL_ENDL;
+    // However many args there are in args, stream each of them to 'out'.
+    for (auto arg : args)
+    {
+        out << arg;
+    }
+    return out;
 }
 
 } // anonymous namespace        
 
 //static
-void LLSingletonBase::logwarns(std::initializer_list<std::string_view> args)
+void LLSingletonBase::logwarns(const string_params& args)
 {
-    log(LLError::LEVEL_WARN, args);
+    LL_WARNS("LLSingleton") << args << LL_ENDL;
 }
 
 //static
-void LLSingletonBase::loginfos(std::initializer_list<std::string_view> args)
+void LLSingletonBase::loginfos(const string_params& args)
 {
-    log(LLError::LEVEL_INFO, args);
+    LL_INFOS("LLSingleton") << args << LL_ENDL;
 }
 
 //static
-void LLSingletonBase::logdebugs(std::initializer_list<std::string_view> args)
+void LLSingletonBase::logdebugs(const string_params& args)
 {
-    log(LLError::LEVEL_DEBUG, args);
+    LL_DEBUGS("LLSingleton") << args << LL_ENDL;
 }
 
 //static
-void LLSingletonBase::logerrs(std::initializer_list<std::string_view> args)
+void LLSingletonBase::logerrs(const string_params& args)
 {
-    log(LLError::LEVEL_ERROR, args);
-    // The other important side effect of LL_ERRS() is
-    // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG)
-    LLERROR_CRASH;
+    LL_ERRS("LLSingleton") << args << LL_ENDL;
 }
 
 std::string LLSingletonBase::demangle(const char* mangled)
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index b9570d42db1..2eb39c6c8cf 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -112,10 +112,13 @@ class LLSingletonBase: private boost::noncopyable
     void capture_dependency();
 
     // delegate logging calls to llsingleton.cpp
-    static void logerrs  (std::initializer_list<std::string_view>);
-    static void logwarns (std::initializer_list<std::string_view>);
-    static void loginfos (std::initializer_list<std::string_view>);
-    static void logdebugs(std::initializer_list<std::string_view>);
+public:
+    typedef std::initializer_list<std::string_view> string_params;
+protected:
+    static void logerrs  (const string_params&);
+    static void logwarns (const string_params&);
+    static void loginfos (const string_params&);
+    static void logdebugs(const string_params&);
     static std::string demangle(const char* mangled);
     // these classname() declarations restate template functions declared in
     // llerror.h because we avoid #including that here
-- 
GitLab