5#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
6#include <QtSystemDetection>
10#include <QMutexLocker>
11#include <QWaitCondition>
15#include <QCoreApplication>
19#include <QSocketNotifier>
22#include "mythconfig.h"
34#if CONFIG_SYSTEMD_JOURNAL
35#define SD_JOURNAL_SUPPRESS_LOCATION 1
36#include <systemd/sd-journal.h>
104 LOG(VB_GENERAL, LOG_INFO, QString(
"Added logging to %1")
114 LOG(VB_GENERAL, LOG_INFO, QString(
"Removed logging to %1")
122 QByteArray ba =
filename.toLocal8Bit();
123 const char *
file = ba.constData();
146 LOG(VB_GENERAL, LOG_INFO, QString(
"Rolled logging on %1") .arg(
m_handle));
156 std::string line = item->
toString();
162 LOG(VB_GENERAL, LOG_ERR,
163 QString(
"Closed Log output to %1 due to unrecoverable error(s).").arg(
m_handle));
173SyslogLogger::SyslogLogger(
bool open) :
178 openlog(
nullptr, LOG_NDELAY, 0 );
182 LOG(VB_GENERAL, LOG_INFO,
"Added syslogging");
186SyslogLogger::~SyslogLogger()
188 LOG(VB_GENERAL, LOG_INFO,
"Removing syslogging");
193SyslogLogger *SyslogLogger::create(QMutex *mutex,
bool open)
195 auto *
logger =
dynamic_cast<SyslogLogger *
>(
loggerMap.value(
"",
nullptr));
202 logger =
new SyslogLogger(open);
213 if (!m_opened || item->
facility() <= 0)
217 syslog(item->
level() | item->
facility(),
"%s[%d]: %c %s %s:%d (%s) %s",
218 qPrintable(item->
appName()), item->
pid(), shortname,
225#if CONFIG_SYSTEMD_JOURNAL
227JournalLogger::JournalLogger() :
230 LOG(VB_GENERAL, LOG_INFO,
"Added journal logging");
234JournalLogger::~JournalLogger()
236 LOG(VB_GENERAL, LOG_INFO,
"Removing journal logging");
239JournalLogger *JournalLogger::create(QMutex *mutex)
241 auto *
logger =
dynamic_cast<JournalLogger *
>(
loggerMap.value(
"",
nullptr));
248 logger =
new JournalLogger();
260 "MESSAGE=%s", qUtf8Printable(item->
message()),
261 "PRIORITY=%d", item->
level(),
262 "CODE_FILE=%s", qUtf8Printable(item->
file()),
263 "CODE_LINE=%d", item->
line(),
264 "CODE_FUNC=%s", qUtf8Printable(item->
function()),
265 "SYSLOG_IDENTIFIER=%s", qUtf8Printable(item->
appName()),
266 "SYSLOG_PID=%d", item->
pid(),
267 "MYTH_THREAD=%s", qUtf8Printable(item->
threadName()),
315 Qt::QueuedConnection);
317 qRegisterMetaType<QList<QByteArray> >(
"QList<QByteArray>");
321 qApp->processEvents(QEventLoop::AllEvents, 10);
322 qApp->sendPostedEvents(
nullptr, QEvent::DeferredDelete);
343 if ((processed & 127) == 0)
345 qApp->processEvents(QEventLoop::AllEvents, 10);
346 qApp->sendPostedEvents(
nullptr, QEvent::DeferredDelete);
361 while (!loggers.isEmpty())
375 LOG(VB_GENERAL, LOG_INFO,
"SIGHUP received, rolling log files.");
379 QMap<QString, LoggerBase *>::iterator it;
382 it.value()->reopen();
394 logItem->
m_itemEpoch = nowAsDuration<std::chrono::seconds>();
404 QString logfile = item->
logFile();
405 if (!logfile.isEmpty())
410 loggers->insert(0,
logger);
421 loggers->insert(0,
logger);
424#if CONFIG_SYSTEMD_JOURNAL
426 if (facility == SYSTEMD_JOURNAL_FACILITY)
431 loggers->insert(0,
logger);
438 logItem->
m_itemEpoch = nowAsDuration<std::chrono::seconds>();
449 for (
auto *it : std::as_const(*logItem->
m_itemList))
465 std::this_thread::sleep_for(10ms);
static void logger(cdio_log_level_t level, const char *message)
File-based logger - used for logfiles and console.
static FileLogger * create(const QString &filename, QMutex *mutex)
std::ofstream m_ofstream
Output file stream for the log file.
bool logmsg(LoggingItem *item) override
Process a log message, writing to the logfile.
~FileLogger() override
FileLogger deconstructor - close the logfile.
void reopen(void) override
Reopen the logfile after a SIGHUP.
FileLogger(const char *filename)
FileLogger constructor.
The logging thread that forwards received messages to the consuming loggers via ZeroMQ.
void run(void) override
Run the log forwarding thread.
static void handleSigHup(void)
SIGHUP handler - reopen all open logfiles for logrollers.
static void forwardMessage(LoggingItem *item)
LogForwardThread()
LogForwardThread constructor.
void stop(void)
Stop the thread by setting the abort flag.
~LogForwardThread() override
LogForwardThread destructor.
bool m_aborted
Flag to abort the thread.
void incomingSigHup(void)
Base class for the various logging mechanisms.
virtual ~LoggerBase()
LoggerBase Deconstructor.
QString m_handle
semi-opaque handle for identifying instance
LoggerBase(const char *string)
LoggerBase Constructor.
The logging items that are generated by LOG() and are sent to the console.
char getLevelChar(void)
Get the message log level as a single character.
std::string toString()
Long format to string.
This is a wrapper around QThread that does several additional things.
bool isRunning(void) const
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
void logForwardMessage(LoggingItem *item)
QList< LoggerBase * > LoggerList
static LoggerListItem * gLoggerList
bool logForwardStart(void)
static QMap< QString, LoggerBase * > loggerMap
static QMutex loggerMapMutex
static QMutex gLoggerListMutex
static LoggingItemList gLogItemList
static QWaitCondition gLogItemListNotEmpty
static QMutex gLogItemListMutex
void logForwardStop(void)
LogForwardThread * logForwardThread
QList< LoggingItem * > LoggingItemList
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
std::chrono::seconds m_itemEpoch