Skip to content

Commit

Permalink
Merge branch 'master' of github.com:MythTV/mythtv
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-h committed Apr 4, 2020
2 parents f7f1f74 + d7762d3 commit b6e77e8
Show file tree
Hide file tree
Showing 30 changed files with 916 additions and 311 deletions.
6 changes: 0 additions & 6 deletions mythtv/libs/libmythbase/compat.h
Expand Up @@ -389,12 +389,6 @@ static __inline struct tm *localtime_r(const time_t *timep, struct tm *result)
}
#endif

#ifdef _WIN32
# define PREFIX64 "I64"
#else
# define PREFIX64 "ll"
#endif

#ifdef ANDROID
#ifndef S_IREAD
#define S_IREAD S_IRUSR
Expand Down
168 changes: 92 additions & 76 deletions mythtv/libs/libmythbase/logging.cpp
Expand Up @@ -89,9 +89,6 @@ LogPropagateOpts logPropagateOpts {false, 0, 0, true, ""};
QString logPropagateArgs;
QStringList logPropagateArgList;

#define TIMESTAMP_MAX 30
#define MAX_STRING_LENGTH (LOGLINE_MAX+120)

LogLevel_t logLevel = LOG_INFO;

bool verboseInitialized = false;
Expand Down Expand Up @@ -151,15 +148,10 @@ LoggingItem::LoggingItem(const char *_file, const char *_function,
LoggingItem::~LoggingItem()
{
free(m_file);

free(m_function);

free(m_threadName);

free(m_appName);

free(m_table);

free(m_logFile);
}

Expand All @@ -177,7 +169,7 @@ QByteArray LoggingItem::toByteArray(void)
/// \return C-string of the thread name
char *LoggingItem::getThreadName(void)
{
static constexpr char kSUnknown[] = "thread_unknown";
static constexpr char const *kSUnknown = "thread_unknown";

if( m_threadName )
return m_threadName;
Expand Down Expand Up @@ -229,6 +221,35 @@ void LoggingItem::setThreadTid(void)
}
}

/// \brief Convert numerical timestamp to a readable date and time.
QString LoggingItem::getTimestamp (void) const
{
#if QT_VERSION < QT_VERSION_CHECK(5,8,0)
QDateTime epoch = QDateTime::fromTime_t(m_epoch).toUTC();
#else
QDateTime epoch = QDateTime::fromSecsSinceEpoch(m_epoch);
#endif
QString timestamp = epoch.toString("yyyy-MM-dd HH:mm:ss");
return timestamp;
}

QString LoggingItem::getTimestampUs (void) const
{
QString timestamp = getTimestamp();
timestamp += QString(".%1").arg(m_usec,6,10,QChar('0'));
return timestamp;
}

/// \brief Get the message log level as a single character.
char LoggingItem::getLevelChar (void)
{
QMutexLocker locker(&loglevelMapMutex);
LoglevelMap::iterator it = loglevelMap.find(m_level);
if (it != loglevelMap.end())
return (*it)->shortname;
return '-';
}

/// \brief LoggerThread constructor. Enables debugging of thread registration
/// and deregistration if the VERBOSE_THREADS environment variable is
/// set.
Expand Down Expand Up @@ -344,11 +365,9 @@ void LoggerThread::handleItem(LoggingItem *item)

if (debugRegistration)
{
snprintf(item->m_message, LOGLINE_MAX,
"Thread 0x%" PREFIX64 "X (%" PREFIX64
"d) registered as \'%s\'",
item->m_threadId,
item->m_tid,
item->m_message = QString("Thread 0x%1 (%2) registered as \'%3\'")
.arg(QString::number(item->m_threadId,16),
QString::number(item->m_tid),
logThreadHash[item->m_threadId]);
}
}
Expand All @@ -370,19 +389,17 @@ void LoggerThread::handleItem(LoggingItem *item)
{
if (debugRegistration)
{
snprintf(item->m_message, LOGLINE_MAX,
"Thread 0x%" PREFIX64 "X (%" PREFIX64
"d) deregistered as \'%s\'",
item->m_threadId,
(long long int)tid,
item->m_message = QString("Thread 0x%1 (%2) deregistered as \'%3\'")
.arg(QString::number(item->m_threadId,16),
QString::number(tid),
logThreadHash[item->m_threadId]);
}
char *threadName = logThreadHash.take(item->m_threadId);
free(threadName);
}
}

if (item->m_message[0] != '\0')
if (!item->m_message.isEmpty())
{
/// TODO: This converts the LoggingItem to json for sending to
/// the log server. Now that the log server is gone, it just
Expand All @@ -400,7 +417,7 @@ void LoggerThread::handleItem(LoggingItem *item)

/// \brief Process a log message, writing to the console
/// \param item LoggingItem containing the log message to process
bool LoggerThread::logConsole(LoggingItem *item)
bool LoggerThread::logConsole(LoggingItem *item) const
{
if (m_quiet || (m_progress && item->m_level > LOG_ERR))
return false;
Expand All @@ -411,52 +428,49 @@ bool LoggerThread::logConsole(LoggingItem *item)
item->IncrRef();

#ifndef Q_OS_ANDROID
char line[MAX_STRING_LENGTH];
std::string line;

if (item->m_type & kStandardIO)
{
snprintf(line, MAX_STRING_LENGTH, "%s", item->m_message);
line = qPrintable(item->m_message);
}
else
{
char usPart[9];
char timestamp[TIMESTAMP_MAX];
time_t epoch = item->epoch();
struct tm tm {};
localtime_r(&epoch, &tm);
strftime(timestamp, TIMESTAMP_MAX-8, "%Y-%m-%d %H:%M:%S",
static_cast<const struct tm *>(&tm));
snprintf(usPart, 9, ".%06d", static_cast<int>(item->m_usec));
strcat(timestamp, usPart);
char shortname = '-';

{
QMutexLocker locker(&loglevelMapMutex);
LoglevelDef *lev = loglevelMap.value(item->m_level, nullptr);
if (lev != nullptr)
shortname = lev->shortname;
}
QString timestamp = item->getTimestampUs();
char shortname = item->getLevelChar();

#if CONFIG_DEBUGTYPE
if(item->tid())
if (item->tid())
{
snprintf(line, MAX_STRING_LENGTH, "%s %c [%d/%" PREFIX64 "d] %s %s:%d:%s %s\n", timestamp,
shortname, item->pid(), item->tid(), item->rawThreadName(),
item->m_file, item->m_line, item->m_function, item->m_message);
line = QString("%1 %2 [%3/%4] %5 %6:%7:%8 %9\n")
.arg(timestamp, QString(shortname),
QString::number(item->pid()),
QString::number(item->tid()),
item->rawThreadName(),
item->m_file,
QString::number(item->m_line),
item->m_function,
item->m_message);
}
else
{
snprintf(line, MAX_STRING_LENGTH, "%s %c [%d] %s %s:%d:%s %s\n", timestamp,
shortname, item->pid(), item->rawThreadName(),
item->m_file, item->m_line, item->m_function, item->m_message);
line = QString("%1 %2 [%3] %4 %5:%6:%7 %8\n")
.arg(timestamp, QString(shortname),
QString::number(item->pid()),
item->rawThreadName(),
item->m_file,
QString::number(item->m_line),
item->m_function,
item->m_message);
}
#else
snprintf(line, MAX_STRING_LENGTH, "%s %c %s\n", timestamp,
shortname, item->m_message);
line = qPrintable(QString("%1 %2 %3\n")
.arg(timestamp, QString(shortname),
item->m_message));
#endif
}

(void)write(1, line, strlen(line));
(void)write(1, line.data(), line.size());

#else // Q_OS_ANDROID

Expand All @@ -465,6 +479,7 @@ bool LoggerThread::logConsole(LoggingItem *item)
{
case LOG_EMERG:
aprio = ANDROID_LOG_FATAL;
break;
case LOG_ALERT:
case LOG_CRIT:
case LOG_ERR:
Expand All @@ -487,9 +502,9 @@ bool LoggerThread::logConsole(LoggingItem *item)
}
#if CONFIG_DEBUGTYPE
__android_log_print(aprio, "mfe", "%s:%d:%s %s", item->m_file,
item->m_line, item->m_function, item->m_message);
item->m_line, item->m_function, qPrintable(item->m_message));
#else
__android_log_print(aprio, "mfe", "%s", item->m_message);
__android_log_print(aprio, "mfe", "%s", qPrintable(item->m_message));
#endif
#endif

Expand Down Expand Up @@ -577,16 +592,10 @@ LoggingItem *LoggingItem::create(QByteArray &buf)
/// \param file Filename of source code logging the message
/// \param line Line number within the source of log message source
/// \param function Function name of the log message source
/// \param fromQString true if this message originated from QString
/// \param format printf format string (when not from QString), log message
/// (when from QString)
/// \param ... printf arguments (when not from QString)
/// \param message log message
void LogPrintLine( uint64_t mask, LogLevel_t level, const char *file, int line,
const char *function, int fromQString,
const char *format, ... )
const char *function, QString message)
{
va_list arguments;

int type = kMessage;
type |= (mask & VB_FLUSH) ? kFlush : 0;
type |= (mask & VB_STDIO) ? kStandardIO : 0;
Expand All @@ -595,26 +604,12 @@ void LogPrintLine( uint64_t mask, LogLevel_t level, const char *file, int line,
if (!item)
return;

char *formatcopy = nullptr;
if( fromQString && strchr(format, '%') )
{
QString string(format);
format = strdup(string.replace(logRegExp, "%%").toLocal8Bit()
.constData());
formatcopy = (char *)format;
}

va_start(arguments, format);
vsnprintf(item->m_message, LOGLINE_MAX, format, arguments);
va_end(arguments);

if (formatcopy)
free(formatcopy);
item->m_message = message;

QMutexLocker qLock(&logQueueMutex);

#if defined( _MSC_VER ) && defined( _DEBUG )
OutputDebugStringA( item->m_message );
OutputDebugStringA( qPrintable(item->m_message) );
OutputDebugStringA( "\n" );
#endif

Expand All @@ -638,6 +633,27 @@ void LogPrintLine( uint64_t mask, LogLevel_t level, const char *file, int line,
}
}

/// \brief Format and send a log message into the queue. This is called from
/// the LOG() macro. The intention is minimal blocking of the caller.
/// \param mask Verbosity mask of the message (VB_*)
/// \param level Log level of this message (LOG_* - matching syslog levels)
/// \param file Filename of source code logging the message
/// \param line Line number within the source of log message source
/// \param function Function name of the log message source
/// \param format printf format string (when not from QString), log message
/// (when from QString)
/// \param ... printf arguments (when not from QString)
void LogPrintLineC( uint64_t mask, LogLevel_t level, const char *file, int line,
const char *function, const char *format, ...)
{
va_list arguments;

va_start(arguments, format);
LogPrintLine(mask, level, file, line, function,
QString::asprintf(format, arguments));
va_end(arguments);
}


/// \brief Generate the logPropagateArgs global with the latest logging
/// level, mask, etc to propagate to all of the mythtv programs
Expand Down
22 changes: 10 additions & 12 deletions mythtv/libs/libmythbase/logging.h
Expand Up @@ -81,7 +81,7 @@ class LoggingItem: public QObject, public ReferenceCounter

friend class LoggerThread;
friend void LogPrintLine(uint64_t mask, LogLevel_t level, const char *file, int line,
const char *function, int fromQString, const char *format, ... );
const char *function, QString message);

public:
char *getThreadName(void);
Expand All @@ -91,6 +91,9 @@ class LoggingItem: public QObject, public ReferenceCounter
LoggingType _type);
static LoggingItem *create(QByteArray &buf);
QByteArray toByteArray(void);
QString getTimestamp(void) const;
QString getTimestampUs(void) const;
char getLevelChar(void);

int pid() const { return m_pid; };
qlonglong tid() const { return m_tid; };
Expand All @@ -107,7 +110,7 @@ class LoggingItem: public QObject, public ReferenceCounter
QString appName() const { return QString(m_appName); };
QString table() const { return QString(m_table); };
QString logFile() const { return QString(m_logFile); };
QString message() const { return QString(m_message); };
QString message() const { return m_message; };

void setPid(const int val) { m_pid = val; };
void setTid(const qlonglong val) { m_tid = val; };
Expand All @@ -124,19 +127,14 @@ class LoggingItem: public QObject, public ReferenceCounter
void setAppName(const QString &val) SET_LOGGING_ARG(m_appName)
void setTable(const QString &val) SET_LOGGING_ARG(m_table)
void setLogFile(const QString &val) SET_LOGGING_ARG(m_logFile)
void setMessage(const QString &val)
{
strncpy(m_message, val.toLocal8Bit().constData(), LOGLINE_MAX);
m_message[LOGLINE_MAX] = '\0';
};
void setMessage(const QString &val) { m_message = val; };

const char *rawFile() const { return m_file; };
const char *rawFunction() const { return m_function; };
const char *rawThreadName() const { return m_threadName; };
const char *rawAppName() const { return m_appName; };
const char *rawTable() const { return m_table; };
const char *rawLogFile() const { return m_logFile; };
const char *rawMessage() const { return m_message; };

protected:
int m_pid {-1};
Expand All @@ -154,7 +152,7 @@ class LoggingItem: public QObject, public ReferenceCounter
char *m_appName {nullptr};
char *m_table {nullptr};
char *m_logFile {nullptr};
char m_message[LOGLINE_MAX+1] {0};
QString m_message {};

private:
LoggingItem()
Expand All @@ -171,8 +169,8 @@ class LoggerThread : public QObject, public MThread
{
Q_OBJECT

friend void LogPrintLine(uint64_t mask, LogLevel_t lavel, const char *file, int line,
const char *funcion, int fromQString, const char *format, ... );
friend void LogPrintLine(uint64_t mask, LogLevel_t level, const char *file, int line,
const char *function, QString message);
public:
LoggerThread(QString filename, bool progress, bool quiet, QString table,
int facility);
Expand Down Expand Up @@ -204,7 +202,7 @@ class LoggerThread : public QObject, public MThread
pid_t m_pid; ///< Cached pid value

protected:
bool logConsole(LoggingItem *item);
bool logConsole(LoggingItem *item) const;
};

#endif
Expand Down

0 comments on commit b6e77e8

Please sign in to comment.