first commit
This commit is contained in:
308
project/fm_viewer/fav/Logger.cpp
Normal file
308
project/fm_viewer/fav/Logger.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
/******************************************************************************
|
||||
QtAV: Multimedia framework based on Qt and FFmpeg
|
||||
Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
|
||||
|
||||
* This file is part of QtAV (from 2013)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* DO NOT appear qDebug, qWanring etc in Logger.cpp! They are undefined and redefined to QtAV:Internal::Logger.xxx
|
||||
*/
|
||||
// we need LogLevel so must include QtAV_Global.h
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMutex>
|
||||
#include "_fav_constants.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#ifndef QTAV_NO_LOG_LEVEL
|
||||
|
||||
void ffmpeg_version_print();
|
||||
namespace FAV {
|
||||
namespace Internal {
|
||||
static QString gQtAVLogTag = QString();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
typedef Logger::Context QMessageLogger;
|
||||
#endif
|
||||
|
||||
static void log_helper(QtMsgType msgType, const QMessageLogger *qlog, const char* msg, va_list ap) {
|
||||
static QMutex m;
|
||||
QMutexLocker lock(&m);
|
||||
Q_UNUSED(lock);
|
||||
static int repeat = 0;
|
||||
static QString last_msg;
|
||||
static QtMsgType last_type = QtDebugMsg;
|
||||
QString qmsg(gQtAVLogTag);
|
||||
QString formated;
|
||||
if (msg) {
|
||||
formated = QString().vsprintf(msg, ap);
|
||||
}
|
||||
// repeate check
|
||||
if (last_type == msgType && last_msg == formated) {
|
||||
repeat++;
|
||||
return;
|
||||
}
|
||||
if (repeat > 0) {
|
||||
// print repeat message and current message
|
||||
qmsg = QStringLiteral("%1(repeat %2)%3\n%4%5")
|
||||
.arg(qmsg).arg(repeat).arg(last_msg).arg(qmsg).arg(formated);
|
||||
} else {
|
||||
qmsg += formated;
|
||||
}
|
||||
repeat = 0;
|
||||
last_type = msgType;
|
||||
last_msg = formated;
|
||||
|
||||
// qt_message_output is a public api
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
qt_message_output(msgType, qmsg.toUtf8().constData());
|
||||
return;
|
||||
#else
|
||||
if (!qlog) {
|
||||
QMessageLogContext ctx;
|
||||
qt_message_output(msgType, ctx, qmsg);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
if (msgType == QtWarningMsg)
|
||||
qlog->warning() << qmsg;
|
||||
else if (msgType == QtCriticalMsg)
|
||||
qlog->critical() << qmsg;
|
||||
else if (msgType == QtFatalMsg)
|
||||
qlog->fatal("%s", qmsg.toUtf8().constData());
|
||||
else
|
||||
qlog->debug() << qmsg;
|
||||
#else
|
||||
if (msgType == QtFatalMsg)
|
||||
qlog->fatal("%s", qmsg.toUtf8().constData());
|
||||
#endif //
|
||||
}
|
||||
|
||||
// macro does not support A::##X
|
||||
|
||||
void Logger::debug(const char *msg, ...) const
|
||||
{
|
||||
#if (OFF_OTHER_DEBUG)
|
||||
Q_UNUSED(msg)
|
||||
#else
|
||||
QtAVDebug d; // initialize something. e.g. environment check
|
||||
Q_UNUSED(d);
|
||||
const int v = (int)logLevel();
|
||||
if (v <= (int)LogOff)
|
||||
return;
|
||||
if (v > (int)LogDebug && v < (int)LogAll)
|
||||
return;
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
// can not use ctx.debug() <<... because QT_NO_DEBUG_STREAM maybe defined
|
||||
log_helper(QtDebugMsg, &ctx, msg, ap);
|
||||
va_end(ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Logger::warning(const char *msg, ...) const
|
||||
{
|
||||
QtAVDebug d; // initialize something. e.g. environment check
|
||||
Q_UNUSED(d);
|
||||
const int v = (int)logLevel();
|
||||
if (v <= (int)LogOff)
|
||||
return;
|
||||
if (v > (int)LogWarning && v < (int)LogAll)
|
||||
return;
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
log_helper(QtWarningMsg, &ctx, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::critical(const char *msg, ...) const
|
||||
{
|
||||
QtAVDebug d; // initialize something. e.g. environment check
|
||||
Q_UNUSED(d);
|
||||
const int v = (int)logLevel();
|
||||
if (v <= (int)LogOff)
|
||||
return;
|
||||
if (v > (int)LogCritical && v < (int)LogAll)
|
||||
return;
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
log_helper(QtCriticalMsg, &ctx, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Logger::fatal(const char *msg, ...) const Q_DECL_NOTHROW
|
||||
{
|
||||
QtAVDebug d; // initialize something. e.g. environment check
|
||||
Q_UNUSED(d);
|
||||
const int v = (int)logLevel();
|
||||
/*
|
||||
if (v <= (int)LogOff)
|
||||
abort();
|
||||
if (v > (int)LogFatal && v < (int)LogAll)
|
||||
abort();
|
||||
*/
|
||||
if (v > (int)LogOff) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
log_helper(QtFatalMsg, &ctx, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
// internal used by Logger::fatal(const char*,...) with log level checked, so always do things here
|
||||
void Logger::Context::fatal(const char *msg, ...) const Q_DECL_NOTHROW
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
QString qmsg;
|
||||
if (msg)
|
||||
qmsg += QString().vsprintf(msg, ap);
|
||||
qt_message_output(QtFatalMsg, qmsg.toUtf8().constData());
|
||||
va_end(ap);
|
||||
abort();
|
||||
}
|
||||
#endif //QT_NO_DEBUG_STREAM
|
||||
#endif //QT_VERSION
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
// will print message in ~QDebug()
|
||||
// can not use QDebug on stack. It must lives in QtAVDebug
|
||||
QtAVDebug Logger::debug() const
|
||||
{
|
||||
QtAVDebug d(QtDebugMsg); //// initialize something. e.g. environment check
|
||||
const int v = (int)logLevel();
|
||||
if (v <= (int)LogOff)
|
||||
return d;
|
||||
if (v <= (int)LogDebug || v >= (int)LogAll)
|
||||
d.setQDebug(new QDebug(ctx.debug()));
|
||||
return d; //ref > 0
|
||||
}
|
||||
|
||||
QtAVDebug Logger::warning() const
|
||||
{
|
||||
QtAVDebug d(QtWarningMsg);
|
||||
const int v = (int)logLevel();
|
||||
if (v <= (int)LogOff)
|
||||
return d;
|
||||
if (v <= (int)LogWarning || v >= (int)LogAll)
|
||||
d.setQDebug(new QDebug(ctx.warning()));
|
||||
return d;
|
||||
}
|
||||
|
||||
QtAVDebug Logger::critical() const
|
||||
{
|
||||
QtAVDebug d(QtCriticalMsg);
|
||||
const int v = (int)logLevel();
|
||||
if (v <= (int)LogOff)
|
||||
return d;
|
||||
if (v <= (int)LogCritical || v >= (int)LogAll)
|
||||
d.setQDebug(new QDebug(ctx.critical()));
|
||||
return d;
|
||||
}
|
||||
// no QMessageLogger::fatal()
|
||||
#endif //QT_NO_DEBUG_STREAM
|
||||
|
||||
bool isLogLevelSet();
|
||||
void print_library_info();
|
||||
|
||||
QtAVDebug::QtAVDebug(QtMsgType t, QDebug *d)
|
||||
: type(t)
|
||||
, dbg(0)
|
||||
{
|
||||
if (d)
|
||||
setQDebug(d); // call *dbg << gQtAVLogTag
|
||||
static bool sFirstRun = true;
|
||||
if (!sFirstRun)
|
||||
return;
|
||||
sFirstRun = false;
|
||||
printf("%s\n", aboutQtAV_PlainText().toUtf8().constData());
|
||||
// check environment var and call other functions at first Qt logging call
|
||||
// always override setLogLevel()
|
||||
QByteArray env = qgetenv("QTAV_LOG_LEVEL");
|
||||
if (env.isEmpty())
|
||||
env = qgetenv("QTAV_LOG");
|
||||
if (!env.isEmpty()) {
|
||||
bool ok = false;
|
||||
const int level = env.toInt(&ok);
|
||||
if (ok) {
|
||||
if (level < (int)LogOff)
|
||||
setLogLevel(LogOff);
|
||||
else if (level > (int)LogAll)
|
||||
setLogLevel(LogAll);
|
||||
else
|
||||
setLogLevel((LogLevel)level);
|
||||
} else {
|
||||
env = env.toLower();
|
||||
if (env.endsWith("off"))
|
||||
setLogLevel(LogOff);
|
||||
else if (env.endsWith("debug"))
|
||||
setLogLevel(LogDebug);
|
||||
else if (env.endsWith("warning"))
|
||||
setLogLevel(LogWarning);
|
||||
else if (env.endsWith("critical"))
|
||||
setLogLevel(LogCritical);
|
||||
else if (env.endsWith("fatal"))
|
||||
setLogLevel(LogFatal);
|
||||
else if (env.endsWith("all") || env.endsWith("default"))
|
||||
setLogLevel(LogAll);
|
||||
}
|
||||
}
|
||||
env = qgetenv("QTAV_LOG_TAG");
|
||||
if (!env.isEmpty()) {
|
||||
gQtAVLogTag = QString::fromUtf8(env);
|
||||
}
|
||||
|
||||
if ((int)logLevel() > (int)LogOff) {
|
||||
print_library_info();
|
||||
}
|
||||
}
|
||||
|
||||
QtAVDebug::~QtAVDebug()
|
||||
{
|
||||
}
|
||||
|
||||
void QtAVDebug::setQDebug(QDebug *d)
|
||||
{
|
||||
dbg = QSharedPointer<QDebug>(d);
|
||||
if (dbg && !gQtAVLogTag.isEmpty()) {
|
||||
*dbg << gQtAVLogTag;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
QtAVDebug debug(const char *msg, ...)
|
||||
{
|
||||
if ((int)logLevel() > (int)Debug && logLevel() != All) {
|
||||
return QtAVDebug();
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, msg); // use variable arg list
|
||||
QMessageLogContext ctx;
|
||||
log_helper(QtDebugMsg, &ctx, msg, ap);
|
||||
va_end(ap);
|
||||
return QtAVDebug();
|
||||
}
|
||||
#endif
|
||||
|
||||
} //namespace Internal
|
||||
} // namespace FAV
|
||||
|
||||
#endif //QTAV_NO_LOG_LEVEL
|
||||
Reference in New Issue
Block a user