mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-12 01:22:41 +02:00
Initial implementation
This commit is contained in:
parent
cd91f9f273
commit
ad4f0c1a8c
3 changed files with 156 additions and 20 deletions
|
@ -21,6 +21,16 @@ if (APPLE)
|
|||
target_link_libraries(${TARGET_NAME} ${FRAMEWORK_IOKIT} ${CORE_FOUNDATION} ${OpenGL})
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
find_package(Journald)
|
||||
|
||||
if (${JOURNALD_FOUND})
|
||||
target_link_libraries(${TARGET_NAME} ${JOURNALD_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${JOURNALD_INCLUDE_DIR})
|
||||
target_compile_definitions(${TARGET_NAME} PUBLIC HAS_JOURNALD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_zlib()
|
||||
target_nsight()
|
||||
target_json()
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include <QtCore/QTimer>
|
||||
#include <QRecursiveMutex>
|
||||
|
||||
#ifdef HAS_JOURNALD
|
||||
#include <systemd/sd-journal.h>
|
||||
#endif
|
||||
|
||||
QRecursiveMutex LogHandler::_mutex;
|
||||
|
||||
LogHandler& LogHandler::getInstance() {
|
||||
|
@ -51,6 +55,10 @@ LogHandler::LogHandler() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_JOURNALD
|
||||
_useJournald = true;
|
||||
#endif
|
||||
|
||||
auto optionList = logOptions.split(",");
|
||||
|
||||
for (auto option : optionList) {
|
||||
|
@ -68,6 +76,8 @@ LogHandler::LogHandler() {
|
|||
_shouldDisplayMilliseconds = true;
|
||||
} else if (option == "keep_repeats") {
|
||||
_keepRepeats = true;
|
||||
} else if (option == "nojournald") {
|
||||
_useJournald = false;
|
||||
} else if (option != "") {
|
||||
fprintf(stdout, "Unrecognized option in VIRCADIA_LOG_OPTIONS: '%s'\n", option.toUtf8().constData());
|
||||
}
|
||||
|
@ -142,6 +152,13 @@ void LogHandler::setShouldDisplayMilliseconds(bool shouldDisplayMilliseconds) {
|
|||
_shouldDisplayMilliseconds = shouldDisplayMilliseconds;
|
||||
}
|
||||
|
||||
bool LogHandler::isJournaldAvailable() const {
|
||||
#ifdef HAS_JOURNALD
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LogHandler::flushRepeatedMessages() {
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
@ -163,6 +180,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
|||
if (message.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
// log prefix is in the following format
|
||||
|
@ -196,25 +214,73 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
|||
}
|
||||
}
|
||||
|
||||
// This is returned from this function and wanted by the LogEntityServer,
|
||||
// so we have to have it even when using journald.
|
||||
QString logMessage = QString("%1 %2\n").arg(prefixString, message.split('\n').join('\n' + prefixString + " "));
|
||||
|
||||
const char* color = "";
|
||||
const char* resetColor = "";
|
||||
|
||||
if (_useColor) {
|
||||
color = colorForLogType(type);
|
||||
resetColor = colorReset();
|
||||
}
|
||||
|
||||
if (_keepRepeats || _previousMessage != message) {
|
||||
if (_repeatCount > 0) {
|
||||
fprintf(stdout, "[Previous message was repeated %i times]\n", _repeatCount);
|
||||
if ( _useJournald ) {
|
||||
#ifdef HAS_JOURNALD
|
||||
int priority = LOG_NOTICE;
|
||||
switch(type) {
|
||||
case LogMsgType::LogFatal: priority = LOG_EMERG; break;
|
||||
case LogMsgType::LogCritical: priority = LOG_CRIT; break;
|
||||
case LogMsgType::LogWarning: priority = LOG_WARNING; break;
|
||||
case LogMsgType::LogInfo: priority = LOG_INFO; break;
|
||||
case LogMsgType::LogDebug: priority = LOG_DEBUG; break;
|
||||
case LogMsgType::LogSuppressed: priority = LOG_DEBUG; break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized log type: %i", (int)type);
|
||||
}
|
||||
|
||||
fprintf(stdout, "%s%s%s", color, qPrintable(logMessage), resetColor);
|
||||
_repeatCount = 0;
|
||||
size_t threadID = (size_t)QThread::currentThreadId();
|
||||
QString sd_file = QString("CODE_FILE=%1").arg(context.file);
|
||||
QString sd_line = QString("CODE_LINE=%1").arg(context.line);
|
||||
|
||||
int retval = sd_journal_send_with_location(sd_file.toUtf8().constData(),
|
||||
sd_line.toUtf8().constData(),
|
||||
context.function == NULL ? "(unknown)" : context.function,
|
||||
"MESSAGE=%s", message.toUtf8().constData(),
|
||||
"PRIORITY=%i", priority,
|
||||
"CATEGORY=%s", context.category,
|
||||
"TID=%i", threadID,
|
||||
NULL);
|
||||
|
||||
if ( retval != 0 ) {
|
||||
fprintf(stderr, "Failed to log message, error %i: ", retval);
|
||||
fprintf(stderr, "file=%s, line=%i, func=%s, prio=%i, msg=%s\n",
|
||||
context.file,
|
||||
context.line,
|
||||
context.function,
|
||||
priority,
|
||||
message.toUtf8().constData()
|
||||
);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
_repeatCount++;
|
||||
const char* color = "";
|
||||
const char* resetColor = "";
|
||||
|
||||
if (_useColor) {
|
||||
color = colorForLogType(type);
|
||||
resetColor = colorReset();
|
||||
}
|
||||
|
||||
if (_keepRepeats || _previousMessage != message) {
|
||||
if (_repeatCount > 0) {
|
||||
fprintf(stdout, "[Previous message was repeated %i times]\n", _repeatCount);
|
||||
}
|
||||
|
||||
fprintf(stdout, "%s%s%s", color, qPrintable(logMessage), resetColor);
|
||||
_repeatCount = 0;
|
||||
} else {
|
||||
_repeatCount++;
|
||||
}
|
||||
|
||||
_previousMessage = message;
|
||||
#ifdef Q_OS_WIN
|
||||
// On windows, this will output log lines into the Visual Studio "output" tab
|
||||
OutputDebugStringA(qPrintable(logMessage));
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( !_breakMessages.empty() ) {
|
||||
|
@ -229,6 +295,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
|||
// On windows, this will output log lines into the Visual Studio "output" tab
|
||||
OutputDebugStringA(qPrintable(logMessage));
|
||||
#endif
|
||||
|
||||
return logMessage;
|
||||
}
|
||||
|
||||
|
@ -275,4 +342,4 @@ void LogHandler::printRepeatedMessage(int messageID, LogMsgType type, const QMes
|
|||
void LogHandler::breakOnMessage(const char *message) {
|
||||
QMutexLocker lock(&_mutex);
|
||||
LogHandler::getInstance()._breakMessages.append(QString::fromUtf8(message));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,24 +31,82 @@ enum LogMsgType {
|
|||
LogSuppressed = 100
|
||||
};
|
||||
|
||||
/// Handles custom message handling and sending of stats/logs to Logstash instance
|
||||
///
|
||||
|
||||
/**
|
||||
* @brief Handles custom message handling and sending of stats/logs to Logstash instance
|
||||
*
|
||||
*/
|
||||
class LogHandler : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief Returns the one instance of the LogHandler object
|
||||
*
|
||||
* @return LogHandler&
|
||||
*/
|
||||
static LogHandler& getInstance();
|
||||
|
||||
/// sets the target name to output via the verboseMessageHandler, called once before logging begins
|
||||
/// \param targetName the desired target name to output in logs
|
||||
/**
|
||||
* @brief Set the Target Name to output via the verboseMessageHandler
|
||||
*
|
||||
* Called once before logging begins
|
||||
*
|
||||
* @param targetName the desired target name to output in logs
|
||||
*/
|
||||
void setTargetName(const QString& targetName);
|
||||
|
||||
/**
|
||||
* @brief Set whether to output the process ID
|
||||
*
|
||||
* @note This has no effect when logging with journald, the PID is always logged
|
||||
*
|
||||
* @param shouldOutputProcessID Whether to output the PID
|
||||
*/
|
||||
void setShouldOutputProcessID(bool shouldOutputProcessID);
|
||||
|
||||
/**
|
||||
* @brief Set whether to output the thread ID
|
||||
*
|
||||
* @param shouldOutputThreadID
|
||||
*/
|
||||
void setShouldOutputThreadID(bool shouldOutputThreadID);
|
||||
|
||||
/**
|
||||
* @brief Set whether to display timestamps with milliseconds
|
||||
*
|
||||
* @param shouldDisplayMilliseconds
|
||||
*/
|
||||
void setShouldDisplayMilliseconds(bool shouldDisplayMilliseconds);
|
||||
|
||||
/**
|
||||
* @brief Set whether to use Journald, if it's available
|
||||
*
|
||||
* @param shouldUseJournald Whether to use journald
|
||||
*/
|
||||
void setShouldUseJournald(bool shouldUseJournald);
|
||||
|
||||
/**
|
||||
* @brief Whether Journald is available on this version/system.
|
||||
*
|
||||
* Support is available depending on compile options and only on Linux.
|
||||
*
|
||||
* @return true Journald is available
|
||||
* @return false Journald is not available
|
||||
*/
|
||||
bool isJournaldAvailable() const;
|
||||
|
||||
QString printMessage(LogMsgType type, const QMessageLogContext& context, const QString &message);
|
||||
|
||||
/// a qtMessageHandler that can be hooked up to a target that links to Qt
|
||||
/// prints various process, message type, and time information
|
||||
/**
|
||||
* @brief A qtMessageHandler that can be hooked up to a target that links to Qt
|
||||
*
|
||||
* Prints various process, message type, and time information
|
||||
*
|
||||
* @param type Log message type
|
||||
* @param context Context of the log message (source file, line, function)
|
||||
* @param message Log message
|
||||
*/
|
||||
static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message);
|
||||
|
||||
int newRepeatedMessageID();
|
||||
|
@ -89,6 +147,7 @@ private:
|
|||
bool _shouldDisplayMilliseconds { false };
|
||||
bool _useColor { false };
|
||||
bool _keepRepeats { false };
|
||||
bool _useJournald { false };
|
||||
|
||||
QString _previousMessage;
|
||||
int _repeatCount { 0 };
|
||||
|
|
Loading…
Reference in a new issue