#include "utils.h" #include #include #include #include #include #include #include typedef struct { std::chrono::time_point start; } timer; static int _log_level = LOG_INFO; static timer *_timer = nullptr; static QString formattedMessage(const char *format, va_list args) { va_list countArgs; va_copy(countArgs, args); const int length = std::vsnprintf(nullptr, 0, format, countArgs); va_end(countArgs); if (length < 0) { return QString::fromUtf8(format); } std::vector buffer(static_cast(length) + 1); std::vsnprintf(buffer.data(), buffer.size(), format, args); return QString::fromUtf8(buffer.data(), length); } extern "C" { int logLevel() { return _log_level; } void setLogLevel(int l) { _log_level = l; } const char *logIndicator(int l) { switch(l) { case LOG_ERROR: return "error"; case LOG_INFO: return "info"; case LOG_DEBUG: return "debug"; case LOG_WARNING: return "warning"; } return "unknown"; } double logElapsedSeconds() { if (_timer == nullptr) { _timer = new timer; _timer->start = std::chrono::system_clock::now(); } const auto current = std::chrono::system_clock::now(); const auto milliseconds = std::chrono::duration_cast( current - _timer->start) .count(); return milliseconds / 1000.0; } void logMessage(int level, const char *format, ...) { if (logLevel() < level) { return; } va_list args; va_start(args, format); const QString message = formattedMessage(format, args); va_end(args); QJsonObject object; object.insert(QStringLiteral("topic"), QStringLiteral("webview-backend")); object.insert(QStringLiteral("level"), QString::fromLatin1(logIndicator(level))); object.insert(QStringLiteral("elapsed"), logElapsedSeconds()); object.insert(QStringLiteral("message"), message); const QByteArray json = QJsonDocument(object).toJson(QJsonDocument::Compact); std::fprintf(stderr, "json:%s\n", json.constData()); std::fflush(stderr); } }