fix: use qlogging in eventsub lib (through a hoop) (#6161)

This commit is contained in:
pajlada
2025-04-19 17:10:12 +02:00
committed by GitHub
parent 9d557146b4
commit 1f10935d78
14 changed files with 134 additions and 14 deletions
+3
View File
@@ -55,3 +55,6 @@
[submodule "lib/twitch-eventsub-ws/lib/date"]
path = lib/twitch-eventsub-ws/lib/date
url = https://github.com/HowardHinnant/date.git
[submodule "lib/twitch-eventsub-ws/lib/fmt"]
path = lib/twitch-eventsub-ws/lib/fmt
url = https://github.com/fmtlib/fmt
+1
View File
@@ -20,6 +20,7 @@
- Bugfix: Fixed an issue where Splits could get lost by dragging it onto your Recycle Bin. (#6147)
- Bugfix: Fixed some Twitch commands not getting tab-completed correctly. (#6143)
- Bugfix: Fixed shared chat badges displaying pixelated when Chatterino is scaled too much. (#6146)
- Bugfix: Fixed a crash that could occur when eventsub was enabled and Chatterino was attached to a conhost on Windows that was later gone. (#6161)
- Dev: Mini refactor of Split. (#6148)
- Dev: Conan will no longer generate a `CMakeUserPresets.json` file. (#6117)
- Dev: Pass `--force-openssl` when installing from CMake in Qt 6.8+. (#6129)
@@ -170,11 +170,12 @@ void BM_ParseAndHandleMessages(benchmark::State &state)
{
auto messages = readMessages();
auto log = std::make_shared<NullLogger>();
std::unique_ptr<Listener> listener = std::make_unique<NoopListener>();
boost::asio::io_context ioc;
boost::asio::ssl::context ssl(
boost::asio::ssl::context::method::tls_client);
auto sess = std::make_shared<Session>(ioc, ssl, std::move(listener));
auto sess = std::make_shared<Session>(ioc, ssl, std::move(listener), log);
for (auto _ : state)
{
@@ -0,0 +1,27 @@
#pragma once
#include <string_view>
namespace chatterino::eventsub::lib {
class Logger
{
public:
virtual ~Logger() = default;
virtual void debug(std::string_view msg) = 0;
virtual void warn(std::string_view msg) = 0;
};
class NullLogger : public Logger
{
public:
void debug(std::string_view msg) override
{
}
void warn(std::string_view msg) override
{
}
};
} // namespace chatterino::eventsub::lib
@@ -1,5 +1,7 @@
#pragma once
#include "twitch-eventsub-ws/logger.hpp"
#include <boost/asio.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
@@ -23,7 +25,8 @@ public:
// Resolver and socket require an io_context
explicit Session(boost::asio::io_context &ioc,
boost::asio::ssl::context &ctx,
std::unique_ptr<Listener> listener);
std::unique_ptr<Listener> listener,
std::shared_ptr<Logger> log_);
// Start the asynchronous operation
void run(std::string _host, std::string _port, std::string _path,
@@ -63,6 +66,7 @@ private:
void checkKeepalive();
std::shared_ptr<Logger> log;
boost::asio::ip::tcp::resolver resolver;
boost::beast::websocket::stream<
boost::beast::ssl_stream<boost::beast::tcp_stream>>
@@ -53,6 +53,7 @@ target_include_directories(${PROJECT_NAME}
"${CMAKE_CURRENT_SOURCE_DIR}/../include"
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../lib/date/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../lib/fmt/include"
)
target_link_libraries(${PROJECT_NAME}
+28 -7
View File
@@ -15,10 +15,26 @@
#include <boost/json.hpp>
#include <chrono>
#include <iostream>
#include <memory>
#include <unordered_map>
#if __cpp_lib_format >= 201907L && !defined(__APPLE__)
# include <format>
#else
# define FMT_HEADER_ONLY
# include "fmt/format.h"
#endif
namespace c2fmt {
#if __cpp_lib_format >= 201907L && !defined(__APPLE__)
using std::format;
#else
using fmt::format;
#endif
} // namespace c2fmt
namespace beast = boost::beast;
namespace http = beast::http;
namespace websocket = beast::websocket;
@@ -230,8 +246,10 @@ namespace {
// Resolver and socket require an io_context
Session::Session(boost::asio::io_context &ioc, boost::asio::ssl::context &ctx,
std::unique_ptr<Listener> listener)
: resolver(boost::asio::make_strand(ioc))
std::unique_ptr<Listener> listener,
std::shared_ptr<Logger> log_)
: log(std::move(log_))
, resolver(boost::asio::make_strand(ioc))
, ws(boost::asio::make_strand(ioc), ctx)
, listener(std::move(listener))
{
@@ -418,7 +436,8 @@ void Session::onClose(beast::error_code ec)
void Session::fail(beast::error_code ec, std::string_view op)
{
std::cerr << op << ": " << ec.message() << " (" << ec.location() << ")\n";
this->log->warn(c2fmt::format("{}: {} ({})", op, ec.message(),
ec.location().to_string()));
if (!this->ws.is_open() && this->listener)
{
if (this->keepaliveTimer)
@@ -505,7 +524,8 @@ boost::system::error_code Session::onSessionWelcome(
this->keepaliveTimeout =
std::chrono::seconds{payload.keepaliveTimeoutSeconds.value_or(60)} * 2;
assert(!this->keepaliveTimer);
std::cerr << "Keepalive: " << this->keepaliveTimeout.count() << 's';
this->log->debug(
c2fmt::format("Keepalive: {}s", this->keepaliveTimeout.count()));
this->checkKeepalive();
return {};
@@ -551,7 +571,7 @@ void Session::checkKeepalive()
{
if (!this->receivedMessage)
{
std::cerr << "Keepalive timeout, closing\n";
this->log->debug("Keepalive timeout, closing");
if (this->listener)
{
this->listener->onClose(std::move(this->listener), {});
@@ -572,7 +592,8 @@ void Session::checkKeepalive()
this->keepaliveTimer->async_wait([this](boost::system::error_code ec) {
if (ec)
{
std::cerr << "Keepalive timer cancelled: " << ec.message() << '\n';
this->log->warn(
c2fmt::format("Keepalive timer cancelled: {}", ec.message()));
return;
}
this->checkKeepalive();
+2 -1
View File
@@ -153,11 +153,12 @@ TEST_P(TestHandleMessageP, Run)
{
auto buf = readToFlatBuffer(filePath(GetParam() + ".json"));
auto log = std::make_shared<NullLogger>();
std::unique_ptr<Listener> listener = std::make_unique<NoOpListener>();
boost::asio::io_context ioc;
boost::asio::ssl::context ssl(
boost::asio::ssl::context::method::tls_client);
auto sess = std::make_shared<Session>(ioc, ssl, std::move(listener));
auto sess = std::make_shared<Session>(ioc, ssl, std::move(listener), log);
auto ec = sess->handleMessage(buf);
ASSERT_FALSE(ec.failed())
<< ec.what() << ec.message() << ec.location().to_string();
+27
View File
@@ -0,0 +1,27 @@
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.
+29 -2
View File
@@ -40,8 +40,35 @@ const auto &LOG = chatterinoTwitchEventSub;
namespace chatterino::eventsub {
class QLogProxy : public lib::Logger
{
public:
QLogProxy(const QLoggingCategory &loggingCategory_)
: loggingCategory(loggingCategory_)
{
}
void debug(std::string_view msg) override
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
qCDebug(this->loggingCategory).noquote() << msg;
#endif
}
void warn(std::string_view msg) override
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
qCWarning(this->loggingCategory).noquote() << msg;
#endif
}
private:
const QLoggingCategory &loggingCategory;
};
Controller::Controller()
: userAgent(QStringLiteral("chatterino/%1 (%2)")
: logProxy(std::shared_ptr<lib::Logger>(new QLogProxy(LOG())))
, userAgent(QStringLiteral("chatterino/%1 (%2)")
.arg(Version::instance().version(),
Version::instance().commitHash())
.toUtf8()
@@ -456,7 +483,7 @@ void Controller::createConnection(std::string host, std::string port,
}
auto connection = std::make_shared<lib::Session>(
this->ioContext, sslContext, std::move(listener));
this->ioContext, sslContext, std::move(listener), this->logProxy);
this->registerConnection(connection);
@@ -2,6 +2,7 @@
#include "providers/twitch/eventsub/SubscriptionHandle.hpp"
#include "providers/twitch/eventsub/SubscriptionRequest.hpp"
#include "twitch-eventsub-ws/logger.hpp"
#include "twitch-eventsub-ws/session.hpp"
#include "util/ExponentialBackoff.hpp"
#include "util/ThreadGuard.hpp"
@@ -91,6 +92,8 @@ private:
void clearConnections();
std::shared_ptr<lib::Logger> logProxy;
const std::string userAgent;
std::string eventSubHost;
+2
View File
@@ -132,6 +132,8 @@ AboutPage::AboutPage()
addLicense(form.getElement(), "Howard Hinnant's date.h",
"https://github.com/HowardHinnant/date",
":/licenses/howard-hinnant-date.txt");
addLicense(form.getElement(), "{fmt}", "https://fmt.dev",
":/licenses/fmtlib.txt");
}
// Attributions
+3 -2
View File
@@ -304,13 +304,14 @@ TEST_P(TestEventSubMessagesP, Run)
input = snapshot->input().toArray();
}
auto log = std::make_shared<eventsub::lib::NullLogger>();
std::unique_ptr<eventsub::lib::Listener> listener =
std::make_unique<eventsub::Connection>();
boost::asio::io_context ioc;
boost::asio::ssl::context ssl(
boost::asio::ssl::context::method::tls_client);
auto sess =
std::make_shared<eventsub::lib::Session>(ioc, ssl, std::move(listener));
auto sess = std::make_shared<eventsub::lib::Session>(
ioc, ssl, std::move(listener), log);
for (const auto inputRef : input)
{