aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llerror.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llerror.cpp69
1 files changed, 63 insertions, 6 deletions
diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp
index 0e7db89..b74b288 100644
--- a/linden/indra/llcommon/llerror.cpp
+++ b/linden/indra/llcommon/llerror.cpp
@@ -408,6 +408,8 @@ namespace LLError
408 LevelMap functionLevelMap; 408 LevelMap functionLevelMap;
409 LevelMap classLevelMap; 409 LevelMap classLevelMap;
410 LevelMap fileLevelMap; 410 LevelMap fileLevelMap;
411 LevelMap tagLevelMap;
412 std::map<std::string, unsigned int> uniqueLogMessages;
411 413
412 LLError::FatalFunction crashFunction; 414 LLError::FatalFunction crashFunction;
413 LLError::TimeFunction timeFunction; 415 LLError::TimeFunction timeFunction;
@@ -494,11 +496,17 @@ namespace LLError
494namespace LLError 496namespace LLError
495{ 497{
496 CallSite::CallSite(ELevel level, 498 CallSite::CallSite(ELevel level,
497 const char* file, int line, 499 const char* file,
498 const std::type_info& class_info, const char* function) 500 int line,
501 const std::type_info& class_info,
502 const char* function,
503 const char* broadTag,
504 const char* narrowTag,
505 bool printOnce)
499 : mLevel(level), mFile(file), mLine(line), 506 : mLevel(level), mFile(file), mLine(line),
500 mClassInfo(class_info), mFunction(function), 507 mClassInfo(class_info), mFunction(function),
501 mCached(false), mShouldLog(false) 508 mCached(false), mShouldLog(false),
509 mBroadTag(broadTag), mNarrowTag(narrowTag), mPrintOnce(printOnce)
502 { } 510 { }
503 511
504 512
@@ -552,6 +560,15 @@ namespace
552#endif 560#endif
553 561
554 LogControlFile& e = LogControlFile::fromDirectory(dir); 562 LogControlFile& e = LogControlFile::fromDirectory(dir);
563
564 // NOTE: We want to explicitly load the file before we add it to the event timer
565 // that checks for changes to the file. Else, we're not actually loading the file yet,
566 // and most of the initialization happens without any attention being paid to the
567 // log control file. Not to mention that when it finally gets checked later,
568 // all log statements that have been evaluated already become dirty and need to be
569 // evaluated for printing again. So, make sure to call checkAndReload()
570 // before addToEventTimer().
571 e.checkAndReload();
555 e.addToEventTimer(); 572 e.addToEventTimer();
556 } 573 }
557} 574}
@@ -625,6 +642,14 @@ namespace LLError
625 g.invalidateCallSites(); 642 g.invalidateCallSites();
626 s.fileLevelMap[file_name] = level; 643 s.fileLevelMap[file_name] = level;
627 } 644 }
645
646 void setTagLevel(const std::string& tag_name, ELevel level)
647 {
648 Globals& g = Globals::get();
649 Settings& s = Settings::get();
650 g.invalidateCallSites();
651 s.tagLevelMap[tag_name] = level;
652 }
628} 653}
629 654
630namespace { 655namespace {
@@ -674,6 +699,8 @@ namespace LLError
674 s.functionLevelMap.clear(); 699 s.functionLevelMap.clear();
675 s.classLevelMap.clear(); 700 s.classLevelMap.clear();
676 s.fileLevelMap.clear(); 701 s.fileLevelMap.clear();
702 s.tagLevelMap.clear();
703 s.uniqueLogMessages.clear();
677 704
678 setPrintLocation(config["print-location"]); 705 setPrintLocation(config["print-location"]);
679 setDefaultLevel(decodeLevel(config["default-level"])); 706 setDefaultLevel(decodeLevel(config["default-level"]));
@@ -689,6 +716,7 @@ namespace LLError
689 setLevels(s.functionLevelMap, entry["functions"], level); 716 setLevels(s.functionLevelMap, entry["functions"], level);
690 setLevels(s.classLevelMap, entry["classes"], level); 717 setLevels(s.classLevelMap, entry["classes"], level);
691 setLevels(s.fileLevelMap, entry["files"], level); 718 setLevels(s.fileLevelMap, entry["files"], level);
719 setLevels(s.tagLevelMap, entry["tags"], level);
692 } 720 }
693 } 721 }
694} 722}
@@ -850,7 +878,7 @@ namespace {
850 return false; 878 return false;
851 } 879 }
852 880
853 level = i->second; 881 level = i->second;
854 return true; 882 return true;
855 } 883 }
856 884
@@ -929,9 +957,15 @@ namespace LLError
929 957
930 ELevel compareLevel = s.defaultLevel; 958 ELevel compareLevel = s.defaultLevel;
931 959
932 checkLevelMap(s.functionLevelMap, function_name, compareLevel) 960 // The most specific match found will be used as the log level,
961 // since the computation short circuits.
962 // So, in increasing order of importance:
963 // Default < Broad Tag < File < Class < Function < Narrow Tag
964 ((site.mNarrowTag != NULL) ? checkLevelMap(s.tagLevelMap, site.mNarrowTag, compareLevel) : false)
965 || checkLevelMap(s.functionLevelMap, function_name, compareLevel)
933 || checkLevelMap(s.classLevelMap, class_name, compareLevel) 966 || checkLevelMap(s.classLevelMap, class_name, compareLevel)
934 || checkLevelMap(s.fileLevelMap, abbreviateFile(site.mFile), compareLevel); 967 || checkLevelMap(s.fileLevelMap, abbreviateFile(site.mFile), compareLevel)
968 || ((site.mBroadTag != NULL) ? checkLevelMap(s.tagLevelMap, site.mBroadTag, compareLevel) : false);
935 969
936 site.mCached = true; 970 site.mCached = true;
937 g.addCallSite(site); 971 g.addCallSite(site);
@@ -1018,6 +1052,29 @@ namespace LLError
1018 #endif 1052 #endif
1019 prefix << site.mFunction << ": "; 1053 prefix << site.mFunction << ": ";
1020 } 1054 }
1055
1056 if (site.mPrintOnce)
1057 {
1058 std::map<std::string, unsigned int>::iterator messageIter = s.uniqueLogMessages.find(message);
1059 if (messageIter != s.uniqueLogMessages.end())
1060 {
1061 messageIter->second++;
1062 unsigned int num_messages = messageIter->second;
1063 if (num_messages == 10 || num_messages == 50 || (num_messages % 100) == 0)
1064 {
1065 prefix << "ONCE (" << num_messages << "th time seen): ";
1066 }
1067 else
1068 {
1069 return;
1070 }
1071 }
1072 else
1073 {
1074 prefix << "ONCE: ";
1075 s.uniqueLogMessages[message] = 1;
1076 }
1077 }
1021 1078
1022 prefix << message; 1079 prefix << message;
1023 message = prefix.str(); 1080 message = prefix.str();