summaryrefslogtreecommitdiff
path: root/indra/llcommon/llerror.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llerror.cpp')
-rw-r--r--indra/llcommon/llerror.cpp1714
1 files changed, 857 insertions, 857 deletions
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 0f48ce16b2..e4843a88eb 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llerror.cpp
* @date December 2006
* @brief error message system
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -65,91 +65,91 @@
namespace {
#if LL_WINDOWS
- void debugger_print(const std::string& s)
- {
- // Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C
- // which works just fine under the windows debugger, but can cause users who
- // have enabled SEHOP exception chain validation to crash due to interactions
- // between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707
- //
- if (IsDebuggerPresent())
- {
- // Need UTF16 for Unicode OutputDebugString
- //
- if (s.size())
- {
- OutputDebugString(utf8str_to_utf16str(s).c_str());
- OutputDebugString(TEXT("\n"));
- }
- }
- }
+ void debugger_print(const std::string& s)
+ {
+ // Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C
+ // which works just fine under the windows debugger, but can cause users who
+ // have enabled SEHOP exception chain validation to crash due to interactions
+ // between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707
+ //
+ if (IsDebuggerPresent())
+ {
+ // Need UTF16 for Unicode OutputDebugString
+ //
+ if (s.size())
+ {
+ OutputDebugString(utf8str_to_utf16str(s).c_str());
+ OutputDebugString(TEXT("\n"));
+ }
+ }
+ }
#else
- class RecordToSyslog : public LLError::Recorder
- {
- public:
- RecordToSyslog(const std::string& identity)
- : mIdentity(identity)
- {
- openlog(mIdentity.c_str(), LOG_CONS|LOG_PID, LOG_LOCAL0);
- // we need to set the string from a local copy of the string
- // since apparanetly openlog expects the const char* to remain
- // valid even after it returns (presumably until closelog)
- }
-
- ~RecordToSyslog()
- {
- closelog();
- }
+ class RecordToSyslog : public LLError::Recorder
+ {
+ public:
+ RecordToSyslog(const std::string& identity)
+ : mIdentity(identity)
+ {
+ openlog(mIdentity.c_str(), LOG_CONS|LOG_PID, LOG_LOCAL0);
+ // we need to set the string from a local copy of the string
+ // since apparanetly openlog expects the const char* to remain
+ // valid even after it returns (presumably until closelog)
+ }
+
+ ~RecordToSyslog()
+ {
+ closelog();
+ }
virtual bool enabled() override
{
return LLError::getEnabledLogTypesMask() & 0x01;
}
-
- virtual void recordMessage(LLError::ELevel level,
- const std::string& message) override
- {
+
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message) override
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
- int syslogPriority = LOG_CRIT;
- switch (level) {
- case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break;
- case LLError::LEVEL_INFO: syslogPriority = LOG_INFO; break;
- case LLError::LEVEL_WARN: syslogPriority = LOG_WARNING; break;
- case LLError::LEVEL_ERROR: syslogPriority = LOG_CRIT; break;
- default: syslogPriority = LOG_CRIT;
- }
-
- syslog(syslogPriority, "%s", message.c_str());
- }
- private:
- std::string mIdentity;
- };
+ int syslogPriority = LOG_CRIT;
+ switch (level) {
+ case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break;
+ case LLError::LEVEL_INFO: syslogPriority = LOG_INFO; break;
+ case LLError::LEVEL_WARN: syslogPriority = LOG_WARNING; break;
+ case LLError::LEVEL_ERROR: syslogPriority = LOG_CRIT; break;
+ default: syslogPriority = LOG_CRIT;
+ }
+
+ syslog(syslogPriority, "%s", message.c_str());
+ }
+ private:
+ std::string mIdentity;
+ };
#endif
- class RecordToFile : public LLError::Recorder
- {
- public:
- RecordToFile(const std::string& filename):
- mName(filename)
- {
- mFile.open(filename.c_str(), std::ios_base::out | std::ios_base::app);
- if (!mFile)
- {
- LL_INFOS() << "Error setting log file to " << filename << LL_ENDL;
- }
- else
- {
- if (!LLError::getAlwaysFlush())
- {
- mFile.sync_with_stdio(false);
- }
- }
- }
-
- ~RecordToFile()
- {
- mFile.close();
- }
+ class RecordToFile : public LLError::Recorder
+ {
+ public:
+ RecordToFile(const std::string& filename):
+ mName(filename)
+ {
+ mFile.open(filename.c_str(), std::ios_base::out | std::ios_base::app);
+ if (!mFile)
+ {
+ LL_INFOS() << "Error setting log file to " << filename << LL_ENDL;
+ }
+ else
+ {
+ if (!LLError::getAlwaysFlush())
+ {
+ mFile.sync_with_stdio(false);
+ }
+ }
+ }
+
+ ~RecordToFile()
+ {
+ mFile.close();
+ }
virtual bool enabled() override
{
@@ -159,7 +159,7 @@ namespace {
return LLError::getEnabledLogTypesMask() & 0x02;
#endif
}
-
+
bool okay() const { return mFile.good(); }
std::string getFilename() const { return mName; }
@@ -178,25 +178,25 @@ namespace {
}
}
- private:
- const std::string mName;
- llofstream mFile;
- };
-
-
- class RecordToStderr : public LLError::Recorder
- {
- public:
- RecordToStderr(bool timestamp) : mUseANSI(checkANSI())
- {
+ private:
+ const std::string mName;
+ llofstream mFile;
+ };
+
+
+ class RecordToStderr : public LLError::Recorder
+ {
+ public:
+ RecordToStderr(bool timestamp) : mUseANSI(checkANSI())
+ {
this->showMultiline(true);
- }
-
+ }
+
virtual bool enabled() override
{
return LLError::getEnabledLogTypesMask() & 0x04;
}
-
+
LL_FORCE_INLINE std::string createBoldANSI()
{
std::string ansi_code;
@@ -231,12 +231,12 @@ namespace {
return ansi_code;
}
- virtual void recordMessage(LLError::ELevel level,
- const std::string& message) override
- {
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message) override
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
// The default colors for error, warn and debug are now a bit more pastel
- // and easier to read on the default (black) terminal background but you
+ // and easier to read on the default (black) terminal background but you
// now have the option to set the color of each via an environment variables:
// LL_ANSI_ERROR_COLOR_CODE (default is red)
// LL_ANSI_WARN_COLOR_CODE (default is blue)
@@ -256,75 +256,75 @@ namespace {
static std::string s_ansi_warn = createANSI(s_ansi_warn_code); // default is blue
static std::string s_ansi_debug = createANSI(s_ansi_debug_code); // default is magenta
- if (mUseANSI)
- {
+ if (mUseANSI)
+ {
writeANSI((level == LLError::LEVEL_ERROR) ? s_ansi_error :
(level == LLError::LEVEL_WARN) ? s_ansi_warn :
s_ansi_debug, message);
- }
+ }
else
{
LL_PROFILE_ZONE_NAMED("fprintf");
fprintf(stderr, "%s\n", message.c_str());
}
- }
-
- private:
- bool mUseANSI;
+ }
+
+ private:
+ bool mUseANSI;
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
- {
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
static std::string s_ansi_bold = createBoldANSI(); // bold text
static std::string s_ansi_reset = createResetANSI(); // reset
- // ANSI color code escape sequence, message, and reset in one fprintf call
+ // ANSI color code escape sequence, message, and reset in one fprintf call
// Default all message levels to bold so we can distinguish our own messages from those dumped by subprocesses and libraries.
- fprintf(stderr, "%s%s\n%s", ansi_code.c_str(), message.c_str(), s_ansi_reset.c_str() );
- }
-
- static bool checkANSI(void)
- {
- // Check whether it's okay to use ANSI; if stderr is
- // a tty then we assume yes. Can be turned off with
- // the LL_NO_ANSI_COLOR env var.
- return (0 != isatty(2)) &&
- (NULL == getenv("LL_NO_ANSI_COLOR"));
- }
- };
-
- class RecordToFixedBuffer : public LLError::Recorder
- {
- public:
- RecordToFixedBuffer(LLLineBuffer* buffer)
+ fprintf(stderr, "%s%s\n%s", ansi_code.c_str(), message.c_str(), s_ansi_reset.c_str() );
+ }
+
+ static bool checkANSI(void)
+ {
+ // Check whether it's okay to use ANSI; if stderr is
+ // a tty then we assume yes. Can be turned off with
+ // the LL_NO_ANSI_COLOR env var.
+ return (0 != isatty(2)) &&
+ (NULL == getenv("LL_NO_ANSI_COLOR"));
+ }
+ };
+
+ class RecordToFixedBuffer : public LLError::Recorder
+ {
+ public:
+ RecordToFixedBuffer(LLLineBuffer* buffer)
: mBuffer(buffer)
{
this->showMultiline(true);
this->showTags(false);
this->showLocation(false);
}
-
+
virtual bool enabled() override
{
return LLError::getEnabledLogTypesMask() & 0x08;
}
-
- virtual void recordMessage(LLError::ELevel level,
- const std::string& message) override
- {
+
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message) override
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
- mBuffer->addLine(message);
- }
-
- private:
- LLLineBuffer* mBuffer;
- };
+ mBuffer->addLine(message);
+ }
+
+ private:
+ LLLineBuffer* mBuffer;
+ };
#if LL_WINDOWS
- class RecordToWinDebug: public LLError::Recorder
- {
- public:
- RecordToWinDebug()
- {
+ class RecordToWinDebug: public LLError::Recorder
+ {
+ public:
+ RecordToWinDebug()
+ {
this->showMultiline(true);
this->showTags(false);
this->showLocation(false);
@@ -334,154 +334,154 @@ namespace {
{
return LLError::getEnabledLogTypesMask() & 0x10;
}
-
- virtual void recordMessage(LLError::ELevel level,
- const std::string& message) override
- {
+
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message) override
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
- debugger_print(message);
- }
- };
+ debugger_print(message);
+ }
+ };
#endif
}
namespace
{
- std::string className(const std::type_info& type)
- {
- return LLError::Log::demangle(type.name());
- }
+ std::string className(const std::type_info& type)
+ {
+ return LLError::Log::demangle(type.name());
+ }
} // anonymous
namespace LLError
{
- std::string Log::demangle(const char* mangled)
- {
+ std::string Log::demangle(const char* mangled)
+ {
#ifdef __GNUC__
- // GCC: type_info::name() returns a mangled class name,st demangle
- // passing nullptr, 0 forces allocation of a unique buffer we can free
- // fixing MAINT-8724 on OSX 10.14
- int status = -1;
- char* name = abi::__cxa_demangle(mangled, nullptr, 0, &status);
- std::string result(name ? name : mangled);
- free(name);
- return result;
+ // GCC: type_info::name() returns a mangled class name,st demangle
+ // passing nullptr, 0 forces allocation of a unique buffer we can free
+ // fixing MAINT-8724 on OSX 10.14
+ int status = -1;
+ char* name = abi::__cxa_demangle(mangled, nullptr, 0, &status);
+ std::string result(name ? name : mangled);
+ free(name);
+ return result;
#elif LL_WINDOWS
- // Visual Studio: type_info::name() includes the text "class " at the start
- std::string name = mangled;
- for (const auto& prefix : std::vector<std::string>{ "class ", "struct " })
- {
- if (0 == name.compare(0, prefix.length(), prefix))
- {
- return name.substr(prefix.length());
- }
- }
- // huh, that's odd, we should see one or the other prefix -- but don't
- // try to log unless logging is already initialized
- // in Python, " or ".join(vector) -- but in C++, a PITB
- LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
- << name << "'" << LL_ENDL;
- return name;
+ // Visual Studio: type_info::name() includes the text "class " at the start
+ std::string name = mangled;
+ for (const auto& prefix : std::vector<std::string>{ "class ", "struct " })
+ {
+ if (0 == name.compare(0, prefix.length(), prefix))
+ {
+ return name.substr(prefix.length());
+ }
+ }
+ // huh, that's odd, we should see one or the other prefix -- but don't
+ // try to log unless logging is already initialized
+ // in Python, " or ".join(vector) -- but in C++, a PITB
+ LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
+ << name << "'" << LL_ENDL;
+ return name;
#else // neither GCC nor Visual Studio
- return mangled;
+ return mangled;
#endif
- }
+ }
} // LLError
namespace
{
- std::string functionName(const std::string& preprocessor_name)
- {
+ std::string functionName(const std::string& preprocessor_name)
+ {
#if LL_WINDOWS
- // DevStudio: the __FUNCTION__ macro string includes
- // the type and/or namespace prefixes
+ // DevStudio: the __FUNCTION__ macro string includes
+ // the type and/or namespace prefixes
- std::string::size_type p = preprocessor_name.rfind(':');
- if (p == std::string::npos)
- {
- return preprocessor_name;
- }
- return preprocessor_name.substr(p + 1);
+ std::string::size_type p = preprocessor_name.rfind(':');
+ if (p == std::string::npos)
+ {
+ return preprocessor_name;
+ }
+ return preprocessor_name.substr(p + 1);
#else
- return preprocessor_name;
+ return preprocessor_name;
#endif
- }
-
-
- class LogControlFile : public LLLiveFile
- {
- LOG_CLASS(LogControlFile);
-
- public:
- static LogControlFile& fromDirectory(const std::string& user_dir, const std::string& app_dir);
-
- virtual bool loadFile();
-
- private:
- LogControlFile(const std::string &filename)
- : LLLiveFile(filename)
- { }
- };
-
- LogControlFile& LogControlFile::fromDirectory(const std::string& user_dir, const std::string& app_dir)
- {
+ }
+
+
+ class LogControlFile : public LLLiveFile
+ {
+ LOG_CLASS(LogControlFile);
+
+ public:
+ static LogControlFile& fromDirectory(const std::string& user_dir, const std::string& app_dir);
+
+ virtual bool loadFile();
+
+ private:
+ LogControlFile(const std::string &filename)
+ : LLLiveFile(filename)
+ { }
+ };
+
+ LogControlFile& LogControlFile::fromDirectory(const std::string& user_dir, const std::string& app_dir)
+ {
// NB: We have no abstraction in llcommon for the "proper"
// delimiter but it turns out that "/" works on all three platforms
-
- std::string file = user_dir + "/logcontrol-dev.xml";
-
- llstat stat_info;
- if (LLFile::stat(file, &stat_info)) {
- // NB: stat returns non-zero if it can't read the file, for example
- // if it doesn't exist. LLFile has no better abstraction for
- // testing for file existence.
-
- file = app_dir + "/logcontrol.xml";
- }
- return * new LogControlFile(file);
- // NB: This instance is never freed
- }
-
- bool LogControlFile::loadFile()
- {
- LLSD configuration;
-
- {
- llifstream file(filename().c_str());
- if (!file.is_open())
- {
- LL_WARNS() << filename() << " failed to open file; not changing configuration" << LL_ENDL;
- return false;
- }
-
- if (LLSDSerialize::fromXML(configuration, file) == LLSDParser::PARSE_FAILURE)
- {
- LL_WARNS() << filename() << " parcing error; not changing configuration" << LL_ENDL;
- return false;
- }
-
- if (! configuration || !configuration.isMap())
- {
- LL_WARNS() << filename() << " missing, ill-formed, or simply undefined"
- " content; not changing configuration"
- << LL_ENDL;
- return false;
- }
- }
-
- LLError::configure(configuration);
- LL_INFOS("LogControlFile") << "logging reconfigured from " << filename() << LL_ENDL;
- return true;
- }
-
-
- typedef std::map<std::string, LLError::ELevel> LevelMap;
- typedef std::vector<LLError::RecorderPtr> Recorders;
- typedef std::vector<LLError::CallSite*> CallSiteVector;
+
+ std::string file = user_dir + "/logcontrol-dev.xml";
+
+ llstat stat_info;
+ if (LLFile::stat(file, &stat_info)) {
+ // NB: stat returns non-zero if it can't read the file, for example
+ // if it doesn't exist. LLFile has no better abstraction for
+ // testing for file existence.
+
+ file = app_dir + "/logcontrol.xml";
+ }
+ return * new LogControlFile(file);
+ // NB: This instance is never freed
+ }
+
+ bool LogControlFile::loadFile()
+ {
+ LLSD configuration;
+
+ {
+ llifstream file(filename().c_str());
+ if (!file.is_open())
+ {
+ LL_WARNS() << filename() << " failed to open file; not changing configuration" << LL_ENDL;
+ return false;
+ }
+
+ if (LLSDSerialize::fromXML(configuration, file) == LLSDParser::PARSE_FAILURE)
+ {
+ LL_WARNS() << filename() << " parcing error; not changing configuration" << LL_ENDL;
+ return false;
+ }
+
+ if (! configuration || !configuration.isMap())
+ {
+ LL_WARNS() << filename() << " missing, ill-formed, or simply undefined"
+ " content; not changing configuration"
+ << LL_ENDL;
+ return false;
+ }
+ }
+
+ LLError::configure(configuration);
+ LL_INFOS("LogControlFile") << "logging reconfigured from " << filename() << LL_ENDL;
+ return true;
+ }
+
+
+ typedef std::map<std::string, LLError::ELevel> LevelMap;
+ typedef std::vector<LLError::RecorderPtr> Recorders;
+ typedef std::vector<LLError::CallSite*> CallSiteVector;
class SettingsConfig : public LLRefCount
{
@@ -492,9 +492,9 @@ namespace
LLError::ELevel mDefaultLevel;
- bool mLogAlwaysFlush;
+ bool mLogAlwaysFlush;
- U32 mEnabledLogTypesMask;
+ U32 mEnabledLogTypesMask;
LevelMap mFunctionLevelMap;
LevelMap mClassLevelMap;
@@ -539,34 +539,34 @@ namespace
mRecorders.clear();
}
- class Globals
- {
+ class Globals
+ {
public:
static Globals* getInstance();
protected:
- Globals();
- public:
- std::string mFatalMessage;
+ Globals();
+ public:
+ std::string mFatalMessage;
- void addCallSite(LLError::CallSite&);
- void invalidateCallSites();
+ void addCallSite(LLError::CallSite&);
+ void invalidateCallSites();
SettingsConfigPtr getSettingsConfig();
void resetSettingsConfig();
LLError::SettingsStoragePtr saveAndResetSettingsConfig();
void restore(LLError::SettingsStoragePtr pSettingsStorage);
- private:
- CallSiteVector callSites;
+ private:
+ CallSiteVector callSites;
SettingsConfigPtr mSettingsConfig;
- };
+ };
- Globals::Globals()
- :
- callSites(),
+ Globals::Globals()
+ :
+ callSites(),
mSettingsConfig(new SettingsConfig())
- {
- }
+ {
+ }
Globals* Globals::getInstance()
@@ -579,20 +579,20 @@ namespace
return &inst;
}
- void Globals::addCallSite(LLError::CallSite& site)
- {
- callSites.push_back(&site);
- }
-
- void Globals::invalidateCallSites()
- {
- for (LLError::CallSite* site : callSites)
- {
+ void Globals::addCallSite(LLError::CallSite& site)
+ {
+ callSites.push_back(&site);
+ }
+
+ void Globals::invalidateCallSites()
+ {
+ for (LLError::CallSite* site : callSites)
+ {
site->invalidate();
- }
-
- callSites.clear();
- }
+ }
+
+ callSites.clear();
+ }
SettingsConfigPtr Globals::getSettingsConfig()
{
@@ -622,77 +622,77 @@ namespace
namespace LLError
{
- CallSite::CallSite(ELevel level,
- const char* file,
- int line,
- const std::type_info& class_info,
- const char* function,
- bool printOnce,
- const char** tags,
- size_t tag_count)
- : mLevel(level),
- mFile(file),
- mLine(line),
- mClassInfo(class_info),
- mFunction(function),
- mCached(false),
- mShouldLog(false),
- mPrintOnce(printOnce),
- mTags(new const char* [tag_count]),
- mTagCount(tag_count)
- {
- switch (mLevel)
- {
+ CallSite::CallSite(ELevel level,
+ const char* file,
+ int line,
+ const std::type_info& class_info,
+ const char* function,
+ bool printOnce,
+ const char** tags,
+ size_t tag_count)
+ : mLevel(level),
+ mFile(file),
+ mLine(line),
+ mClassInfo(class_info),
+ mFunction(function),
+ mCached(false),
+ mShouldLog(false),
+ mPrintOnce(printOnce),
+ mTags(new const char* [tag_count]),
+ mTagCount(tag_count)
+ {
+ switch (mLevel)
+ {
case LEVEL_DEBUG: mLevelString = "DEBUG"; break;
case LEVEL_INFO: mLevelString = "INFO"; break;
case LEVEL_WARN: mLevelString = "WARNING"; break;
case LEVEL_ERROR: mLevelString = "ERROR"; break;
default: mLevelString = "XXX"; break;
- };
+ };
- mLocationString = llformat("%s(%d)", abbreviateFile(mFile).c_str(), mLine);
+ mLocationString = llformat("%s(%d)", abbreviateFile(mFile).c_str(), mLine);
#if LL_WINDOWS
- // DevStudio: __FUNCTION__ already includes the full class name
+ // DevStudio: __FUNCTION__ already includes the full class name
#else
#if LL_LINUX
- // gross, but typeid comparison seems to always fail here with gcc4.1
- if (0 != strcmp(mClassInfo.name(), typeid(NoClassInfo).name()))
+ // gross, but typeid comparison seems to always fail here with gcc4.1
+ if (0 != strcmp(mClassInfo.name(), typeid(NoClassInfo).name()))
#else
- if (mClassInfo != typeid(NoClassInfo))
+ if (mClassInfo != typeid(NoClassInfo))
#endif // LL_LINUX
- {
- mFunctionString = className(mClassInfo) + "::";
- }
+ {
+ mFunctionString = className(mClassInfo) + "::";
+ }
#endif
- mFunctionString += std::string(mFunction);
+ mFunctionString += std::string(mFunction);
- for (int i = 0; i < tag_count; i++)
- {
+ for (int i = 0; i < tag_count; i++)
+ {
if (strchr(tags[i], ' '))
{
LL_ERRS() << "Space is not allowed in a log tag at " << mLocationString << LL_ENDL;
}
- mTags[i] = tags[i];
- }
+ mTags[i] = tags[i];
+ }
mTagString.append("#");
// always construct a tag sequence; will be just a single # if no tag
- for (size_t i = 0; i < mTagCount; i++)
- {
- mTagString.append(mTags[i]);
+ for (size_t i = 0; i < mTagCount; i++)
+ {
+ mTagString.append(mTags[i]);
mTagString.append("#");
- }
- }
-
- CallSite::~CallSite()
- {
- delete []mTags;
- }
-
- void CallSite::invalidate()
- {
- mCached = false;
- }
+ }
+ }
+
+ CallSite::~CallSite()
+ {
+ delete []mTags;
+ }
+
+ void CallSite::invalidate()
+ {
+ mCached = false;
+ }
}
namespace
@@ -729,202 +729,202 @@ namespace
#endif
}
- bool stderrLogWantsTime()
- {
+ bool stderrLogWantsTime()
+ {
#if LL_WINDOWS
- return false;
+ return false;
#else
- return true;
+ return true;
#endif
- }
-
-
- void commonInit(const std::string& user_dir, const std::string& app_dir, bool log_to_stderr = true)
- {
- Globals::getInstance()->resetSettingsConfig();
-
- LLError::setDefaultLevel(LLError::LEVEL_INFO);
- LLError::setAlwaysFlush(true);
- LLError::setEnabledLogTypesMask(0xFFFFFFFF);
- LLError::setTimeFunction(LLError::utcTime);
-
- // log_to_stderr is only false in the unit and integration tests to keep builds quieter
- if (log_to_stderr && shouldLogToStderr())
- {
- LLError::logToStderr();
- }
+ }
+
+
+ void commonInit(const std::string& user_dir, const std::string& app_dir, bool log_to_stderr = true)
+ {
+ Globals::getInstance()->resetSettingsConfig();
+
+ LLError::setDefaultLevel(LLError::LEVEL_INFO);
+ LLError::setAlwaysFlush(true);
+ LLError::setEnabledLogTypesMask(0xFFFFFFFF);
+ LLError::setTimeFunction(LLError::utcTime);
+
+ // log_to_stderr is only false in the unit and integration tests to keep builds quieter
+ if (log_to_stderr && shouldLogToStderr())
+ {
+ LLError::logToStderr();
+ }
#if LL_WINDOWS
- LLError::RecorderPtr recordToWinDebug(new RecordToWinDebug());
- LLError::addRecorder(recordToWinDebug);
+ LLError::RecorderPtr recordToWinDebug(new RecordToWinDebug());
+ LLError::addRecorder(recordToWinDebug);
#endif
- LogControlFile& e = LogControlFile::fromDirectory(user_dir, app_dir);
-
- // NOTE: We want to explicitly load the file before we add it to the event timer
- // that checks for changes to the file. Else, we're not actually loading the file yet,
- // and most of the initialization happens without any attention being paid to the
- // log control file. Not to mention that when it finally gets checked later,
- // all log statements that have been evaluated already become dirty and need to be
- // evaluated for printing again. So, make sure to call checkAndReload()
- // before addToEventTimer().
- e.checkAndReload();
- e.addToEventTimer();
- }
+ LogControlFile& e = LogControlFile::fromDirectory(user_dir, app_dir);
+
+ // NOTE: We want to explicitly load the file before we add it to the event timer
+ // that checks for changes to the file. Else, we're not actually loading the file yet,
+ // and most of the initialization happens without any attention being paid to the
+ // log control file. Not to mention that when it finally gets checked later,
+ // all log statements that have been evaluated already become dirty and need to be
+ // evaluated for printing again. So, make sure to call checkAndReload()
+ // before addToEventTimer().
+ e.checkAndReload();
+ e.addToEventTimer();
+ }
}
namespace LLError
{
- void initForApplication(const std::string& user_dir, const std::string& app_dir, bool log_to_stderr)
- {
- commonInit(user_dir, app_dir, log_to_stderr);
- }
-
- void setFatalFunction(const FatalFunction& f)
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- s->mCrashFunction = f;
- }
-
- FatalFunction getFatalFunction()
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- return s->mCrashFunction;
- }
-
- std::string getFatalMessage()
- {
- return Globals::getInstance()->mFatalMessage;
- }
-
- void setTimeFunction(TimeFunction f)
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- s->mTimeFunction = f;
- }
-
- void setDefaultLevel(ELevel level)
- {
- Globals *g = Globals::getInstance();
- g->invalidateCallSites();
- SettingsConfigPtr s = g->getSettingsConfig();
- s->mDefaultLevel = level;
- }
-
- ELevel getDefaultLevel()
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- return s->mDefaultLevel;
- }
-
- void setAlwaysFlush(bool flush)
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- s->mLogAlwaysFlush = flush;
- }
-
- bool getAlwaysFlush()
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- return s->mLogAlwaysFlush;
- }
-
- void setEnabledLogTypesMask(U32 mask)
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- s->mEnabledLogTypesMask = mask;
- }
-
- U32 getEnabledLogTypesMask()
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- return s->mEnabledLogTypesMask;
- }
-
- void setFunctionLevel(const std::string& function_name, ELevel level)
- {
- Globals *g = Globals::getInstance();
- g->invalidateCallSites();
- SettingsConfigPtr s = g->getSettingsConfig();
- s->mFunctionLevelMap[function_name] = level;
- }
-
- void setClassLevel(const std::string& class_name, ELevel level)
- {
- Globals *g = Globals::getInstance();
- g->invalidateCallSites();
- SettingsConfigPtr s = g->getSettingsConfig();
- s->mClassLevelMap[class_name] = level;
- }
-
- void setFileLevel(const std::string& file_name, ELevel level)
- {
- Globals *g = Globals::getInstance();
- g->invalidateCallSites();
- SettingsConfigPtr s = g->getSettingsConfig();
- s->mFileLevelMap[file_name] = level;
- }
-
- void setTagLevel(const std::string& tag_name, ELevel level)
- {
- Globals *g = Globals::getInstance();
- g->invalidateCallSites();
- SettingsConfigPtr s = g->getSettingsConfig();
- s->mTagLevelMap[tag_name] = level;
- }
-
- LLError::ELevel decodeLevel(std::string name)
- {
- static LevelMap level_names;
- if (level_names.empty())
- {
- level_names["ALL"] = LLError::LEVEL_ALL;
- level_names["DEBUG"] = LLError::LEVEL_DEBUG;
- level_names["INFO"] = LLError::LEVEL_INFO;
- level_names["WARN"] = LLError::LEVEL_WARN;
- level_names["ERROR"] = LLError::LEVEL_ERROR;
- level_names["NONE"] = LLError::LEVEL_NONE;
- }
-
- std::transform(name.begin(), name.end(), name.begin(), toupper);
-
- LevelMap::const_iterator i = level_names.find(name);
- if (i == level_names.end())
- {
- LL_WARNS() << "unrecognized logging level: '" << name << "'" << LL_ENDL;
- return LLError::LEVEL_INFO;
- }
-
- return i->second;
- }
+ void initForApplication(const std::string& user_dir, const std::string& app_dir, bool log_to_stderr)
+ {
+ commonInit(user_dir, app_dir, log_to_stderr);
+ }
+
+ void setFatalFunction(const FatalFunction& f)
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ s->mCrashFunction = f;
+ }
+
+ FatalFunction getFatalFunction()
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ return s->mCrashFunction;
+ }
+
+ std::string getFatalMessage()
+ {
+ return Globals::getInstance()->mFatalMessage;
+ }
+
+ void setTimeFunction(TimeFunction f)
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ s->mTimeFunction = f;
+ }
+
+ void setDefaultLevel(ELevel level)
+ {
+ Globals *g = Globals::getInstance();
+ g->invalidateCallSites();
+ SettingsConfigPtr s = g->getSettingsConfig();
+ s->mDefaultLevel = level;
+ }
+
+ ELevel getDefaultLevel()
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ return s->mDefaultLevel;
+ }
+
+ void setAlwaysFlush(bool flush)
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ s->mLogAlwaysFlush = flush;
+ }
+
+ bool getAlwaysFlush()
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ return s->mLogAlwaysFlush;
+ }
+
+ void setEnabledLogTypesMask(U32 mask)
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ s->mEnabledLogTypesMask = mask;
+ }
+
+ U32 getEnabledLogTypesMask()
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ return s->mEnabledLogTypesMask;
+ }
+
+ void setFunctionLevel(const std::string& function_name, ELevel level)
+ {
+ Globals *g = Globals::getInstance();
+ g->invalidateCallSites();
+ SettingsConfigPtr s = g->getSettingsConfig();
+ s->mFunctionLevelMap[function_name] = level;
+ }
+
+ void setClassLevel(const std::string& class_name, ELevel level)
+ {
+ Globals *g = Globals::getInstance();
+ g->invalidateCallSites();
+ SettingsConfigPtr s = g->getSettingsConfig();
+ s->mClassLevelMap[class_name] = level;
+ }
+
+ void setFileLevel(const std::string& file_name, ELevel level)
+ {
+ Globals *g = Globals::getInstance();
+ g->invalidateCallSites();
+ SettingsConfigPtr s = g->getSettingsConfig();
+ s->mFileLevelMap[file_name] = level;
+ }
+
+ void setTagLevel(const std::string& tag_name, ELevel level)
+ {
+ Globals *g = Globals::getInstance();
+ g->invalidateCallSites();
+ SettingsConfigPtr s = g->getSettingsConfig();
+ s->mTagLevelMap[tag_name] = level;
+ }
+
+ LLError::ELevel decodeLevel(std::string name)
+ {
+ static LevelMap level_names;
+ if (level_names.empty())
+ {
+ level_names["ALL"] = LLError::LEVEL_ALL;
+ level_names["DEBUG"] = LLError::LEVEL_DEBUG;
+ level_names["INFO"] = LLError::LEVEL_INFO;
+ level_names["WARN"] = LLError::LEVEL_WARN;
+ level_names["ERROR"] = LLError::LEVEL_ERROR;
+ level_names["NONE"] = LLError::LEVEL_NONE;
+ }
+
+ std::transform(name.begin(), name.end(), name.begin(), toupper);
+
+ LevelMap::const_iterator i = level_names.find(name);
+ if (i == level_names.end())
+ {
+ LL_WARNS() << "unrecognized logging level: '" << name << "'" << LL_ENDL;
+ return LLError::LEVEL_INFO;
+ }
+
+ return i->second;
+ }
}
namespace {
- void setLevels(LevelMap& map, const LLSD& list, LLError::ELevel level)
- {
- LLSD::array_const_iterator i, end;
- for (i = list.beginArray(), end = list.endArray(); i != end; ++i)
- {
- map[*i] = level;
- }
- }
+ void setLevels(LevelMap& map, const LLSD& list, LLError::ELevel level)
+ {
+ LLSD::array_const_iterator i, end;
+ for (i = list.beginArray(), end = list.endArray(); i != end; ++i)
+ {
+ map[*i] = level;
+ }
+ }
}
namespace LLError
{
- void configure(const LLSD& config)
- {
- Globals *g = Globals::getInstance();
- g->invalidateCallSites();
- SettingsConfigPtr s = g->getSettingsConfig();
-
- s->mFunctionLevelMap.clear();
- s->mClassLevelMap.clear();
- s->mFileLevelMap.clear();
- s->mTagLevelMap.clear();
- s->mUniqueLogMessages.clear();
-
- setDefaultLevel(decodeLevel(config["default-level"]));
+ void configure(const LLSD& config)
+ {
+ Globals *g = Globals::getInstance();
+ g->invalidateCallSites();
+ SettingsConfigPtr s = g->getSettingsConfig();
+
+ s->mFunctionLevelMap.clear();
+ s->mClassLevelMap.clear();
+ s->mFileLevelMap.clear();
+ s->mTagLevelMap.clear();
+ s->mUniqueLogMessages.clear();
+
+ setDefaultLevel(decodeLevel(config["default-level"]));
if (config.has("log-always-flush"))
{
setAlwaysFlush(config["log-always-flush"]);
@@ -933,7 +933,7 @@ namespace LLError
{
setEnabledLogTypesMask(config["enabled-log-types-mask"].asInteger());
}
-
+
if (config.has("settings") && config["settings"].isArray())
{
LLSD sets = config["settings"];
@@ -952,66 +952,66 @@ namespace LLError
}
}
}
- }
+ }
}
namespace LLError
{
- Recorder::Recorder()
- : mWantsTime(true)
+ Recorder::Recorder()
+ : mWantsTime(true)
, mWantsTags(true)
, mWantsLevel(true)
, mWantsLocation(true)
, mWantsFunctionName(true)
, mWantsMultiline(false)
- {
- }
-
- Recorder::~Recorder()
- {
- }
-
- bool Recorder::wantsTime()
- {
- return mWantsTime;
- }
-
- // virtual
- bool Recorder::wantsTags()
- {
- return mWantsTags;
- }
-
- // virtual
- bool Recorder::wantsLevel()
- {
- return mWantsLevel;
- }
-
- // virtual
- bool Recorder::wantsLocation()
- {
- return mWantsLocation;
- }
-
- // virtual
- bool Recorder::wantsFunctionName()
- {
- return mWantsFunctionName;
- }
-
- // virtual
- bool Recorder::wantsMultiline()
- {
- return mWantsMultiline;
- }
+ {
+ }
+
+ Recorder::~Recorder()
+ {
+ }
+
+ bool Recorder::wantsTime()
+ {
+ return mWantsTime;
+ }
+
+ // virtual
+ bool Recorder::wantsTags()
+ {
+ return mWantsTags;
+ }
+
+ // virtual
+ bool Recorder::wantsLevel()
+ {
+ return mWantsLevel;
+ }
+
+ // virtual
+ bool Recorder::wantsLocation()
+ {
+ return mWantsLocation;
+ }
+
+ // virtual
+ bool Recorder::wantsFunctionName()
+ {
+ return mWantsFunctionName;
+ }
+
+ // virtual
+ bool Recorder::wantsMultiline()
+ {
+ return mWantsMultiline;
+ }
void Recorder::showTime(bool show)
{
mWantsTime = show;
}
-
+
void Recorder::showTags(bool show)
{
mWantsTags = show;
@@ -1037,28 +1037,28 @@ namespace LLError
mWantsMultiline = show;
}
- void addRecorder(RecorderPtr recorder)
- {
- if (!recorder)
- {
- return;
- }
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- LLMutexLock lock(&s->mRecorderMutex);
- s->mRecorders.push_back(recorder);
- }
-
- void removeRecorder(RecorderPtr recorder)
- {
- if (!recorder)
- {
- return;
- }
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- LLMutexLock lock(&s->mRecorderMutex);
- s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder),
- s->mRecorders.end());
- }
+ void addRecorder(RecorderPtr recorder)
+ {
+ if (!recorder)
+ {
+ return;
+ }
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ LLMutexLock lock(&s->mRecorderMutex);
+ s->mRecorders.push_back(recorder);
+ }
+
+ void removeRecorder(RecorderPtr recorder)
+ {
+ if (!recorder)
+ {
+ return;
+ }
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ LLMutexLock lock(&s->mRecorderMutex);
+ s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder),
+ s->mRecorders.end());
+ }
// Find an entry in SettingsConfig::mRecorders whose RecorderPtr points to
// a Recorder subclass of type RECORDER. Return, not a RecorderPtr (which
@@ -1127,26 +1127,26 @@ namespace LLError
namespace LLError
{
- void logToFile(const std::string& file_name)
- {
- // remove any previous Recorder filling this role
- removeRecorder<RecordToFile>();
-
- if (!file_name.empty())
- {
- std::shared_ptr<RecordToFile> recordToFile(new RecordToFile(file_name));
- if (recordToFile->okay())
- {
- addRecorder(recordToFile);
- }
- }
- }
-
- std::string logFileName()
- {
- auto found = findRecorder<RecordToFile>();
- return found? found->getFilename() : std::string();
- }
+ void logToFile(const std::string& file_name)
+ {
+ // remove any previous Recorder filling this role
+ removeRecorder<RecordToFile>();
+
+ if (!file_name.empty())
+ {
+ std::shared_ptr<RecordToFile> recordToFile(new RecordToFile(file_name));
+ if (recordToFile->okay())
+ {
+ addRecorder(recordToFile);
+ }
+ }
+ }
+
+ std::string logFileName()
+ {
+ auto found = findRecorder<RecordToFile>();
+ return found? found->getFilename() : std::string();
+ }
void logToStderr()
{
@@ -1157,17 +1157,17 @@ namespace LLError
}
}
- void logToFixedBuffer(LLLineBuffer* fixedBuffer)
- {
- // remove any previous Recorder filling this role
- removeRecorder<RecordToFixedBuffer>();
+ void logToFixedBuffer(LLLineBuffer* fixedBuffer)
+ {
+ // remove any previous Recorder filling this role
+ removeRecorder<RecordToFixedBuffer>();
- if (fixedBuffer)
- {
- RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
- addRecorder(recordToFixedBuffer);
- }
- }
+ if (fixedBuffer)
+ {
+ RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
+ addRecorder(recordToFixedBuffer);
+ }
+ }
}
namespace
@@ -1213,40 +1213,40 @@ namespace
return out.str();
}
- void writeToRecorders(const LLError::CallSite& site, const std::string& message)
- {
+ void writeToRecorders(const LLError::CallSite& site, const std::string& message)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
- LLError::ELevel level = site.mLevel;
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ LLError::ELevel level = site.mLevel;
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
std::string escaped_message;
LLMutexLock lock(&s->mRecorderMutex);
- for (LLError::RecorderPtr& r : s->mRecorders)
- {
+ for (LLError::RecorderPtr& r : s->mRecorders)
+ {
if (!r->enabled())
{
continue;
}
-
- std::ostringstream message_stream;
- if (r->wantsTime() && s->mTimeFunction != NULL)
- {
- message_stream << s->mTimeFunction();
- }
+ std::ostringstream message_stream;
+
+ if (r->wantsTime() && s->mTimeFunction != NULL)
+ {
+ message_stream << s->mTimeFunction();
+ }
message_stream << " ";
-
- if (r->wantsLevel())
+
+ if (r->wantsLevel())
{
- message_stream << site.mLevelString;
+ message_stream << site.mLevelString;
}
message_stream << " ";
-
- if (r->wantsTags())
- {
- message_stream << site.mTagString;
- }
+
+ if (r->wantsTags())
+ {
+ message_stream << site.mTagString;
+ }
message_stream << " ";
if (r->wantsLocation() || level == LLError::LEVEL_ERROR)
@@ -1255,10 +1255,10 @@ namespace
}
message_stream << " ";
- if (r->wantsFunctionName())
- {
- message_stream << site.mFunctionString;
- }
+ if (r->wantsFunctionName())
+ {
+ message_stream << site.mFunctionString;
+ }
message_stream << " : ";
if (r->wantsMultiline())
@@ -1274,250 +1274,250 @@ namespace
message_stream << escaped_message;
}
- r->recordMessage(level, message_stream.str());
- }
- }
+ r->recordMessage(level, message_stream.str());
+ }
+ }
}
namespace {
- // We need a couple different mutexes, but we want to use the same mechanism
- // for both. Make getMutex() a template function with different instances
- // for different MutexDiscriminator values.
- enum MutexDiscriminator
- {
- LOG_MUTEX,
- STACKS_MUTEX
- };
- // Some logging calls happen very early in processing -- so early that our
- // module-static variables aren't yet initialized. getMutex() wraps a
- // function-static LLMutex so that early calls can still have a valid
- // LLMutex instance.
- template <MutexDiscriminator MTX>
- LLMutex* getMutex()
- {
- // guaranteed to be initialized the first time control reaches here
- static LLMutex sMutex;
- return &sMutex;
- }
-
- bool checkLevelMap(const LevelMap& map, const std::string& key,
- LLError::ELevel& level)
- {
- bool stop_checking;
- LevelMap::const_iterator i = map.find(key);
- if (i == map.end())
- {
- return stop_checking = false;
- }
-
- level = i->second;
- return stop_checking = true;
- }
-
- bool checkLevelMap( const LevelMap& map,
- const char *const * keys,
- size_t count,
- LLError::ELevel& level)
- {
- bool found_level = false;
-
- LLError::ELevel tag_level = LLError::LEVEL_NONE;
-
- for (size_t i = 0; i < count; i++)
- {
- LevelMap::const_iterator it = map.find(keys[i]);
- if (it != map.end())
- {
- found_level = true;
- tag_level = llmin(tag_level, it->second);
- }
- }
-
- if (found_level)
- {
- level = tag_level;
- }
- return found_level;
- }
+ // We need a couple different mutexes, but we want to use the same mechanism
+ // for both. Make getMutex() a template function with different instances
+ // for different MutexDiscriminator values.
+ enum MutexDiscriminator
+ {
+ LOG_MUTEX,
+ STACKS_MUTEX
+ };
+ // Some logging calls happen very early in processing -- so early that our
+ // module-static variables aren't yet initialized. getMutex() wraps a
+ // function-static LLMutex so that early calls can still have a valid
+ // LLMutex instance.
+ template <MutexDiscriminator MTX>
+ LLMutex* getMutex()
+ {
+ // guaranteed to be initialized the first time control reaches here
+ static LLMutex sMutex;
+ return &sMutex;
+ }
+
+ bool checkLevelMap(const LevelMap& map, const std::string& key,
+ LLError::ELevel& level)
+ {
+ bool stop_checking;
+ LevelMap::const_iterator i = map.find(key);
+ if (i == map.end())
+ {
+ return stop_checking = false;
+ }
+
+ level = i->second;
+ return stop_checking = true;
+ }
+
+ bool checkLevelMap( const LevelMap& map,
+ const char *const * keys,
+ size_t count,
+ LLError::ELevel& level)
+ {
+ bool found_level = false;
+
+ LLError::ELevel tag_level = LLError::LEVEL_NONE;
+
+ for (size_t i = 0; i < count; i++)
+ {
+ LevelMap::const_iterator it = map.find(keys[i]);
+ if (it != map.end())
+ {
+ found_level = true;
+ tag_level = llmin(tag_level, it->second);
+ }
+ }
+
+ if (found_level)
+ {
+ level = tag_level;
+ }
+ return found_level;
+ }
}
namespace LLError
{
- bool Log::shouldLog(CallSite& site)
- {
+ bool Log::shouldLog(CallSite& site)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
- LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
- if (!lock.isLocked())
- {
- return false;
- }
-
- Globals *g = Globals::getInstance();
- SettingsConfigPtr s = g->getSettingsConfig();
-
- s->mShouldLogCallCounter++;
-
- const std::string& class_name = className(site.mClassInfo);
- std::string function_name = functionName(site.mFunction);
+ LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
+ if (!lock.isLocked())
+ {
+ return false;
+ }
+
+ Globals *g = Globals::getInstance();
+ SettingsConfigPtr s = g->getSettingsConfig();
+
+ s->mShouldLogCallCounter++;
+
+ const std::string& class_name = className(site.mClassInfo);
+ std::string function_name = functionName(site.mFunction);
#if LL_LINUX
- // gross, but typeid comparison seems to always fail here with gcc4.1
- if (0 != strcmp(site.mClassInfo.name(), typeid(NoClassInfo).name()))
+ // gross, but typeid comparison seems to always fail here with gcc4.1
+ if (0 != strcmp(site.mClassInfo.name(), typeid(NoClassInfo).name()))
#else
- if (site.mClassInfo != typeid(NoClassInfo))
+ if (site.mClassInfo != typeid(NoClassInfo))
#endif // LL_LINUX
- {
- function_name = class_name + "::" + function_name;
- }
-
- ELevel compareLevel = s->mDefaultLevel;
-
- // The most specific match found will be used as the log level,
- // since the computation short circuits.
- // So, in increasing order of importance:
- // Default < Tags < File < Class < Function
- checkLevelMap(s->mFunctionLevelMap, function_name, compareLevel)
- || checkLevelMap(s->mClassLevelMap, class_name, compareLevel)
- || checkLevelMap(s->mFileLevelMap, abbreviateFile(site.mFile), compareLevel)
- || (site.mTagCount > 0
- ? checkLevelMap(s->mTagLevelMap, site.mTags, site.mTagCount, compareLevel)
- : false);
-
- site.mCached = true;
- g->addCallSite(site);
- return site.mShouldLog = site.mLevel >= compareLevel;
- }
-
-
- void Log::flush(const std::ostringstream& out, const CallSite& site)
- {
+ {
+ function_name = class_name + "::" + function_name;
+ }
+
+ ELevel compareLevel = s->mDefaultLevel;
+
+ // The most specific match found will be used as the log level,
+ // since the computation short circuits.
+ // So, in increasing order of importance:
+ // Default < Tags < File < Class < Function
+ checkLevelMap(s->mFunctionLevelMap, function_name, compareLevel)
+ || checkLevelMap(s->mClassLevelMap, class_name, compareLevel)
+ || checkLevelMap(s->mFileLevelMap, abbreviateFile(site.mFile), compareLevel)
+ || (site.mTagCount > 0
+ ? checkLevelMap(s->mTagLevelMap, site.mTags, site.mTagCount, compareLevel)
+ : false);
+
+ site.mCached = true;
+ g->addCallSite(site);
+ return site.mShouldLog = site.mLevel >= compareLevel;
+ }
+
+
+ void Log::flush(const std::ostringstream& out, const CallSite& site)
+ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
- LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
- if (!lock.isLocked())
- {
- return;
- }
-
- Globals* g = Globals::getInstance();
- SettingsConfigPtr s = g->getSettingsConfig();
-
- std::string message = out.str();
-
- if (site.mPrintOnce)
- {
- std::ostringstream message_stream;
-
- std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
- if (messageIter != s->mUniqueLogMessages.end())
- {
- messageIter->second++;
- unsigned int num_messages = messageIter->second;
- if (num_messages == 10 || num_messages == 50 || (num_messages % 100) == 0)
- {
- message_stream << "ONCE (" << num_messages << "th time seen): ";
- }
- else
- {
- return;
- }
- }
- else
- {
- message_stream << "ONCE: ";
- s->mUniqueLogMessages[message] = 1;
- }
- message_stream << message;
- message = message_stream.str();
- }
-
- writeToRecorders(site, message);
-
- if (site.mLevel == LEVEL_ERROR)
- {
- g->mFatalMessage = message;
+ LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
+ if (!lock.isLocked())
+ {
+ return;
+ }
+
+ Globals* g = Globals::getInstance();
+ SettingsConfigPtr s = g->getSettingsConfig();
+
+ std::string message = out.str();
+
+ if (site.mPrintOnce)
+ {
+ std::ostringstream message_stream;
+
+ std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
+ if (messageIter != s->mUniqueLogMessages.end())
+ {
+ messageIter->second++;
+ unsigned int num_messages = messageIter->second;
+ if (num_messages == 10 || num_messages == 50 || (num_messages % 100) == 0)
+ {
+ message_stream << "ONCE (" << num_messages << "th time seen): ";
+ }
+ else
+ {
+ return;
+ }
+ }
+ else
+ {
+ message_stream << "ONCE: ";
+ s->mUniqueLogMessages[message] = 1;
+ }
+ message_stream << message;
+ message = message_stream.str();
+ }
+
+ writeToRecorders(site, message);
+
+ if (site.mLevel == LEVEL_ERROR)
+ {
+ g->mFatalMessage = message;
if (s->mCrashFunction)
{
s->mCrashFunction(message);
}
- }
- }
+ }
+ }
}
namespace LLError
{
- SettingsStoragePtr saveAndResetSettings()
- {
- return Globals::getInstance()->saveAndResetSettingsConfig();
- }
-
- void restoreSettings(SettingsStoragePtr pSettingsStorage)
- {
- return Globals::getInstance()->restore(pSettingsStorage);
- }
-
- std::string removePrefix(std::string& s, const std::string& p)
- {
- std::string::size_type where = s.find(p);
- if (where == std::string::npos)
- {
- return s;
- }
-
- return std::string(s, where + p.size());
- }
-
- void replaceChar(std::string& s, char old, char replacement)
- {
- std::string::size_type i = 0;
- std::string::size_type len = s.length();
- for ( ; i < len; i++ )
- {
- if (s[i] == old)
- {
- s[i] = replacement;
- }
- }
- }
-
- std::string abbreviateFile(const std::string& filePath)
- {
- std::string f = filePath;
+ SettingsStoragePtr saveAndResetSettings()
+ {
+ return Globals::getInstance()->saveAndResetSettingsConfig();
+ }
+
+ void restoreSettings(SettingsStoragePtr pSettingsStorage)
+ {
+ return Globals::getInstance()->restore(pSettingsStorage);
+ }
+
+ std::string removePrefix(std::string& s, const std::string& p)
+ {
+ std::string::size_type where = s.find(p);
+ if (where == std::string::npos)
+ {
+ return s;
+ }
+
+ return std::string(s, where + p.size());
+ }
+
+ void replaceChar(std::string& s, char old, char replacement)
+ {
+ std::string::size_type i = 0;
+ std::string::size_type len = s.length();
+ for ( ; i < len; i++ )
+ {
+ if (s[i] == old)
+ {
+ s[i] = replacement;
+ }
+ }
+ }
+
+ std::string abbreviateFile(const std::string& filePath)
+ {
+ std::string f = filePath;
#if LL_WINDOWS
- replaceChar(f, '\\', '/');
+ replaceChar(f, '\\', '/');
#endif
- static std::string indra_prefix = "indra/";
- f = removePrefix(f, indra_prefix);
+ static std::string indra_prefix = "indra/";
+ f = removePrefix(f, indra_prefix);
#if LL_DARWIN
- static std::string newview_prefix = "newview/../";
- f = removePrefix(f, newview_prefix);
+ static std::string newview_prefix = "newview/../";
+ f = removePrefix(f, newview_prefix);
#endif
- return f;
- }
-
- int shouldLogCallCount()
- {
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- return s->mShouldLogCallCounter;
- }
-
- std::string utcTime()
- {
- time_t now = time(NULL);
- const size_t BUF_SIZE = 64;
- char time_str[BUF_SIZE]; /* Flawfinder: ignore */
-
- auto chars = strftime(time_str, BUF_SIZE,
- "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&now));
-
- return chars ? time_str : "time error";
- }
+ return f;
+ }
+
+ int shouldLogCallCount()
+ {
+ SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
+ return s->mShouldLogCallCounter;
+ }
+
+ std::string utcTime()
+ {
+ time_t now = time(NULL);
+ const size_t BUF_SIZE = 64;
+ char time_str[BUF_SIZE]; /* Flawfinder: ignore */
+
+ auto chars = strftime(time_str, BUF_SIZE,
+ "%Y-%m-%dT%H:%M:%SZ",
+ gmtime(&now));
+
+ return chars ? time_str : "time error";
+ }
}
namespace LLError
-{
+{
LLCallStacks::StringVector LLCallStacks::sBuffer ;
//static
@@ -1576,7 +1576,7 @@ namespace LLError
LL_INFOS() << " ************* PRINT OUT LL CALL STACKS ************* " << LL_ENDL;
for (StringVector::const_reverse_iterator ri(sBuffer.rbegin()), re(sBuffer.rend());
ri != re; ++ri)
- {
+ {
LL_INFOS() << (*ri) << LL_ENDL;
}
LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;