Merge pull request #6254 from hyperlogic/tony/log-handler-crash-fix

Fix for rare crash in LogHandler::flushRepeatedMessages()
This commit is contained in:
Brad Hefta-Gaub 2015-10-30 18:47:37 -07:00
commit 88fda01ce2
4 changed files with 67 additions and 41 deletions

View file

@ -74,7 +74,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
// make sure we output process IDs for a child AC otherwise it's insane to parse
LogHandler::getInstance().setShouldOutputPID(true);
LogHandler::getInstance().setShouldOutputProcessID(true);
// setup our _requestAssignment member variable from the passed arguments
_requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool);

View file

@ -44,7 +44,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME);
// make sure we output process IDs for a monitor otherwise it's insane to parse
LogHandler::getInstance().setShouldOutputPID(true);
LogHandler::getInstance().setShouldOutputProcessID(true);
// create a NodeList so we can receive stats from children
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();

View file

@ -12,9 +12,12 @@
#include <qcoreapplication.h>
#include <qdatetime.h>
#include <qdebug.h>
#include <qtimer.h>
#include <QDateTime>
#include <QDebug>
#include <QTimer>
#include <QThread>
#include <QMutexLocker>
#include <QRegExp>
#include "LogHandler.h"
@ -24,7 +27,8 @@ LogHandler& LogHandler::getInstance() {
}
LogHandler::LogHandler() :
_shouldOutputPID(false)
_shouldOutputProcessID(false),
_shouldOutputThreadID(false)
{
// setup our timer to flush the verbose logs every 5 seconds
QTimer* logFlushTimer = new QTimer(this);
@ -57,6 +61,7 @@ const char* stringForLogType(LogMsgType msgType) {
const QString DATE_STRING_FORMAT = "MM/dd hh:mm:ss";
void LogHandler::flushRepeatedMessages() {
QMutexLocker locker(&_repeatedMessageLock);
QHash<QString, int>::iterator message = _repeatMessageCountHash.begin();
while (message != _repeatMessageCountHash.end()) {
@ -81,6 +86,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
if (type == LogDebug) {
// for debug messages, check if this matches any of our regexes for repeated log messages
QMutexLocker locker(&_repeatedMessageLock);
foreach(const QString& regexString, getInstance()._repeatedMessageRegexes) {
QRegExp repeatRegex(regexString);
if (repeatRegex.indexIn(message) != -1) {
@ -101,7 +107,9 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
}
}
}
}
if (type == LogDebug) {
QMutexLocker locker(&_onlyOnceMessageLock);
// see if this message is one we should only print once
foreach(const QString& regexString, getInstance()._onlyOnceMessageRegexes) {
QRegExp onlyOnceRegex(regexString);
@ -120,15 +128,19 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
}
// log prefix is in the following format
// [TIMESTAMP] [DEBUG] [PID] [TARGET] logged string
// [TIMESTAMP] [DEBUG] [PID] [TID] [TARGET] logged string
QString prefixString = QString("[%1]").arg(QDateTime::currentDateTime().toString(DATE_STRING_FORMAT));
prefixString.append(QString(" [%1]").arg(stringForLogType(type)));
if (_shouldOutputPID) {
if (_shouldOutputProcessID) {
prefixString.append(QString(" [%1]").arg(QCoreApplication::instance()->applicationPid()));
}
if (_shouldOutputThreadID) {
size_t threadID = (size_t)QThread::currentThreadId();
prefixString.append(QString(" [%1]").arg(threadID));
}
if (!_targetName.isEmpty()) {
@ -143,3 +155,13 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
getInstance().printMessage((LogMsgType) type, context, message);
}
const QString& LogHandler::addRepeatedMessageRegex(const QString& regexString) {
QMutexLocker locker(&_repeatedMessageLock);
return *_repeatedMessageRegexes.insert(regexString);
}
const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) {
QMutexLocker locker(&_onlyOnceMessageLock);
return *_onlyOnceMessageRegexes.insert(regexString);
}

View file

@ -13,11 +13,11 @@
#ifndef hifi_LogHandler_h
#define hifi_LogHandler_h
#include <qhash.h>
#include <qobject.h>
#include <qregexp.h>
#include <qset.h>
#include <qstring.h>
#include <QHash>
#include <QObject>
#include <QSet>
#include <QString>
#include <QMutex>
const int VERBOSE_LOG_INTERVAL_SECONDS = 5;
@ -39,7 +39,8 @@ public:
/// \param targetName the desired target name to output in logs
void setTargetName(const QString& targetName) { _targetName = targetName; }
void setShouldOutputPID(bool shouldOutputPID) { _shouldOutputPID = shouldOutputPID; }
void setShouldOutputProcessID(bool shouldOutputProcessID) { _shouldOutputProcessID = shouldOutputProcessID; }
void setShouldOutputThreadID(bool shouldOutputThreadID) { _shouldOutputThreadID = shouldOutputThreadID; }
QString printMessage(LogMsgType type, const QMessageLogContext& context, const QString &message);
@ -47,21 +48,24 @@ public:
/// prints various process, message type, and time information
static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message);
const QString& addRepeatedMessageRegex(const QString& regexString) { return *_repeatedMessageRegexes.insert(regexString); }
const QString& addOnlyOnceMessageRegex(const QString& regexString) { return *_onlyOnceMessageRegexes.insert(regexString); }
const QString& addRepeatedMessageRegex(const QString& regexString);
const QString& addOnlyOnceMessageRegex(const QString& regexString);
private:
LogHandler();
void flushRepeatedMessages();
QString _targetName;
bool _shouldOutputPID;
bool _shouldOutputProcessID;
bool _shouldOutputThreadID;
QSet<QString> _repeatedMessageRegexes;
QHash<QString, int> _repeatMessageCountHash;
QHash<QString, QString> _lastRepeatedMessage;
QMutex _repeatedMessageLock;
QSet<QString> _onlyOnceMessageRegexes;
QHash<QString, int> _onlyOnceMessageCountHash;
QMutex _onlyOnceMessageLock;
};
#endif // hifi_LogHandler_h