18 #include <QStringList>    30 #include <sys/syscall.h>    31 #elif defined(__FreeBSD__)    33 #include <sys/ucontext.h>    36 #elif defined(Q_OS_MAC)    37 #include <mach/mach.h>    72                            int Line, LogLevel Level, 
int Type, quint64 Mask)
    74         return new LogItem(File, Function, Line, Level, Type, Mask);
    88     LogItem(
const char *File, 
const char *Function,
    89             int Line, LogLevel Level, 
int Type, quint64 Mask)
    91         threadId((uint64_t)(QThread::currentThreadId())),
    93         line(Line),         type(Type),
    97         function(Function), threadName(nullptr),
   114 #if HAVE_GETTIMEOFDAY   116         gettimeofday(&tv, 
nullptr);
   120         QDateTime date = QDateTime::currentDateTime();
   121         QTime     time = date.time();
   122         epoch = date.toTime_t();
   123         usec = time.msec() * 1000;
   126         localtime_r(&epoch, &tm);
   138             tid = (int64_t)syscall(SYS_gettid);
   139 #elif defined(__FreeBSD__)   141             int dummy = thr_self( &lwpid );
   143             tid = (int64_t)lwpid;
   144 #elif defined(Q_OS_MAC)   145             tid = (int64_t)mach_thread_self();
   159     const char         *
function;
   173     while (!m_aborted || !
gLogQueue.isEmpty())
   177             m_waitEmpty.wakeAll();
   178             m_waitNotEmpty.wait(lock.mutex(), 100);
   216     m_waitNotEmpty.wakeAll();
   223     while (!m_aborted && !
gLogQueue.isEmpty() && t.elapsed() < TimeoutMS)
   225         m_waitNotEmpty.wakeAll();
   226         int left = TimeoutMS - t.elapsed();
   263         QList<LoggerBase *>::iterator it;
   278 #define TIMESTAMP_MAX 30   279 #define MAX_STRING_LENGTH (LOGLINE_MAX+120)   285     QString  name      { QStringLiteral(
"") };
   286     bool     additive  { 
false };
   287     QString  helpText  { QStringLiteral(
"") };
   294     QString     name      { QStringLiteral(
"") };
   295     char        shortname { 
'?' };
   314 void AddVerbose(uint64_t mask, QString name, 
bool additive, QString helptext);
   315 void AddLogLevel(
int value, QString name, 
char shortname);
   337              (
const struct tm *)&Item->
tm );
   338     snprintf(usPart, 5, 
".%03d", (
int)(Item->
usec));
   339     strcat(timestamp, usPart);
   348             shortname = (*it).shortname;
   358         snprintf(fileline, 50, 
"%s (%s:%d)", Item->
function, Item->
file, Item->
line);
   363                  timestamp, shortname, getpid(), tid, threadName, fileline,
   368     return line.trimmed();
   375     m_errorsOnly(ErrorsOnly),
   381         LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Logging to the console"));
   389             LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Moving '%1' to '%2'").arg(
m_fileName, old));
   398         if (!
m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Truncate | QIODevice::Text | QIODevice::Unbuffered))
   400             LOG(VB_GENERAL, LOG_ERR, QStringLiteral(
"Failed to open %1 for logging").arg(
m_fileName));
   404         LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Logging to '%1'").arg(
m_fileName));
   414                                         __LINE__, LOG_INFO, 
kMessage, VB_GENERAL);
   416         strcpy(item->
message, 
m_file.isOpen() ? 
"Closing file logger." : 
"Closing console logger.");
   431     QByteArray line = 
GetLine(Item);
   438     int error = 
m_file.isOpen() ? 
m_file.write(Line) : write(1, Line, Line.size() );
   441         LOG(VB_GENERAL, LOG_ERR,
   442              QStringLiteral(
"Closed Log output due to errors"));
   461     TorcHTTPService(this, QStringLiteral(
"log"), QStringLiteral(
"log"), 
WebLogger::staticMetaObject, QStringLiteral(
"event")),
   473     if (event && event->type() == QEvent::Timer)
   476         bool haschanged = changed;
   487     return QObject::event(event);
   498     if (!
log.open(QIODevice::ReadOnly))
   500     QByteArray result = 
log.readAll();
   516     bool filter = (Item->
mask & VB_NETWORK) && (Item->
level >= LOG_DEBUG);
   519     QByteArray line = 
GetLine(Item);
   536     static const char *unknown = 
"QRunnable";
   539         return (
char*)unknown;
   549             threadName = (
char*)unknown;
   588 void PrintLogLine(uint64_t Mask, LogLevel Level, 
const char *File, 
int Line,
   589                   const char *Function, 
const char *Format, ... )
   592     type |= (Mask & VB_FLUSH) ? 
kFlush : 0;
   599     va_start(arguments, Format);
   627     mask.replace(QRegExp(
" "), QStringLiteral(
","));
   628     mask.remove(QRegExp(
"^,"));
   637     for (
int i = 0; i < gLogPropagationOpts.
quiet; i++)
   643     return gLogPropagationOpts.
quiet;
   647                   const QString &Level, 
bool Propagate)
   661     if (gLogThread->isRunning())
   665     LOG(VB_GENERAL, LOG_NOTICE, QStringLiteral(
"Setting level to LOG_%1")
   668     gLogPropagationOpts.
propagate = Propagate;
   669     gLogPropagationOpts.
quiet = quiet;
   673         QFileInfo finfo(Logfile);
   674         QString path = finfo.path();
   675         gLogPropagationOpts.
path = path;
   680     new FileLogger(QStringLiteral(
""), progress, quiet);
   682     if (!Logfile.isEmpty())
   700         gLogThread = 
nullptr;
   739         item->
threadName = strdup((
char *)QThread::currentThread()->objectName().toLocal8Bit().constData());
   770         if ((*it).name == level.toLower() )
   771             return (LogLevel)(*it).value;
   786     LoglevelMap::iterator it = 
gLoglevelMap.find((
int)level);
   789         return QStringLiteral(
"unknown");
   794 void AddVerbose(uint64_t mask, QString name, 
bool additive, QString helptext)
   802     name = name.toLower();
   819     name = name.toLower();
   833 #undef TORCLOGGINGDEFS_H_   834 #define _IMPLEMENT_VERBOSE   843     m_verbose.replace(QRegExp(
" "), QStringLiteral(
","));
   844     m_verbose.remove(QRegExp(
"^,"));
   846     cerr << 
"Verbose debug levels.\n"   847             "Accepts any combination (separated by comma) of:\n\n";
   849     for (VerboseMap::Iterator vit = 
gVerboseMap.begin();
   852         QString name = QStringLiteral(
"  %1").arg(vit.value().name, -15, 
' ');
   853         if (vit.value().helpText.isEmpty())
   855         cerr << name.toLocal8Bit().constData() << 
" - " <<
   856                 vit.value().helpText.toLocal8Bit().constData() << endl;
   860       "The default for this program appears to be: '-v " <<
   861       m_verbose.toLocal8Bit().constData() << 
"'\n\n"   862       "Most options are additive except for 'none' and 'all'.\n"   863       "These two are semi-exclusive and take precedence over any\n"   864       "other options.  However, you may use something like\n"   865       "'-v none,jobqueue' to receive only JobQueue related messages\n"   866       "and override the default verbosity level.\n\n"   867       "Additive options may also be subtracted from 'all' by\n"   868       "prefixing them with 'no', so you may use '-v all,nodatabase'\n"   869       "to view all but database debug messages.\n\n"   870       "Some debug levels may not apply to this program.\n\n";
   885     if (arg.startsWith(
'-'))
   887         cerr << 
"Invalid or missing argument to -v/--verbose option\n";
   891     QStringList verboseOpts = arg.split(QRegExp(
"\\W+"));
   892     for (QStringList::Iterator it = verboseOpts.begin();
   893          it != verboseOpts.end(); ++it )
   895         option = (*it).toLower();
   896         bool reverseOption = 
false;
   898         if (option != QStringLiteral(
"none") && option.left(2) == QStringLiteral(
"no"))
   900             reverseOption = 
true;
   901             option = option.right(option.length() - 2);
   904         if (option == QStringLiteral(
"help"))
   909         else if (option == QStringLiteral(
"important"))
   911             cerr << 
"The \"important\" log mask is no longer valid.\n";
   913         else if (option == QStringLiteral(
"extra"))
   915             cerr << 
"The \"extra\" log mask is no longer valid.  Please try "   916                     "--loglevel debug instead.\n";
   918         else if (option == QStringLiteral(
"default"))
   961                 cerr << 
"Unknown argument for -v/--verbose: " <<
   962                         option.toLocal8Bit().constData() << endl;;
   980     return QStringLiteral(
"%1 (%2)").arg(strerror(errnum)).arg(errnum);
 
LoggingThread * gLogThread
 
bool Flush(int TimeoutMS=200000)
 
LoggerBase(const QString &FileName)
 
#define TORC_EXIT_INVALID_CMDLINE
 
void SubscriberDeleted(QObject *Subscriber)
 
void PrintLogLine(uint64_t Mask, LogLevel Level, const char *File, int Line, const char *Function, const char *Format,...)
 
void AddLogLevel(int value, QString name, char shortname)
 
QHash< uint64_t, int64_t > gLogThreadtidHash
 
int ParseVerboseArgument(const QString &arg)
 
static void Delete(LogItem *Item)
 
bool Logmsg(LogItem *Item) override
 
QQueue< LogItem * > gLogQueue
 
bool PrintLine(QByteArray &Line) override
 
QList< LoggerBase * > gLoggerList
 
WebLogger(const QString &Filename)
 
int64_t GetThreadTid(LogItem *item)
 
QByteArray GetLine(LogItem *Item)
 
Serves log content to registered subscribers and HTTP clients. 
 
QString gLogPropagationArgs
 
bool event(QEvent *event) override
 
void CalculateLogPropagation(void)
 
QString GetLogLevelName(LogLevel level)
 
char * GetThreadName(LogItem *item)
 
QString gVerboseDefaultStr
 
bool Logmsg(LogItem *Item) override
 
QMap< int, LoglevelDef > LoglevelMap
 
const uint64_t gVerboseDefaultInt
 
bool GetQuietLogPropagation(void)
 
QHash< uint64_t, char * > gLogThreadHash
 
void HandleSubscriberDeleted(QObject *Subscriber)
 
#define MAX_STRING_LENGTH
 
QReadWriteLock m_httpServiceLock
 
LogPropagateOpts gLogPropagationOpts
 
#define LOG(_MASK_, _LEVEL_, _STRING_)
 
void RegisterLoggingThread(void)
 
FileLogger(const QString &Filename, bool ErrorsOnly, int Quiet)
 
uint64_t gUserDefaultValueInt
 
QMap< QString, VerboseDef > VerboseMap
 
void StartLogging(const QString &Logfile, int progress, int quiet, const QString &Level, bool Propagate)
 
LogLevel GetLogLevel(const QString &level)
 
LogItem(const char *File, const char *Function, int Line, LogLevel Level, int Type, quint64 Mask)
 
static LogItem * Create(const char *File, const char *Function, int Line, LogLevel Level, int Type, quint64 Mask)
 
void HandleItem(LogItem *Item)
 
QString gUserDefaultValueStr
 
bool gHaveUserDefaultValues
 
char message[LOGLINE_MAX+1]
 
QString LogErrorToString(int errnum)
 
A Torc specific wrapper around QThread. 
 
void AddVerbose(uint64_t mask, QString name, bool additive, QString helptext)
 
void DeregisterLoggingThread(void)