fix: use qlogging in eventsub lib (through a hoop) (#6161)
This commit is contained in:
@@ -55,3 +55,6 @@
|
|||||||
[submodule "lib/twitch-eventsub-ws/lib/date"]
|
[submodule "lib/twitch-eventsub-ws/lib/date"]
|
||||||
path = lib/twitch-eventsub-ws/lib/date
|
path = lib/twitch-eventsub-ws/lib/date
|
||||||
url = https://github.com/HowardHinnant/date.git
|
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
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
- Bugfix: Fixed an issue where Splits could get lost by dragging it onto your Recycle Bin. (#6147)
|
- 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 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 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: Mini refactor of Split. (#6148)
|
||||||
- Dev: Conan will no longer generate a `CMakeUserPresets.json` file. (#6117)
|
- Dev: Conan will no longer generate a `CMakeUserPresets.json` file. (#6117)
|
||||||
- Dev: Pass `--force-openssl` when installing from CMake in Qt 6.8+. (#6129)
|
- 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 messages = readMessages();
|
||||||
|
|
||||||
|
auto log = std::make_shared<NullLogger>();
|
||||||
std::unique_ptr<Listener> listener = std::make_unique<NoopListener>();
|
std::unique_ptr<Listener> listener = std::make_unique<NoopListener>();
|
||||||
boost::asio::io_context ioc;
|
boost::asio::io_context ioc;
|
||||||
boost::asio::ssl::context ssl(
|
boost::asio::ssl::context ssl(
|
||||||
boost::asio::ssl::context::method::tls_client);
|
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)
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include "twitch-eventsub-ws/logger.hpp"
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/beast/core.hpp>
|
#include <boost/beast/core.hpp>
|
||||||
#include <boost/beast/ssl.hpp>
|
#include <boost/beast/ssl.hpp>
|
||||||
@@ -23,7 +25,8 @@ public:
|
|||||||
// Resolver and socket require an io_context
|
// Resolver and socket require an io_context
|
||||||
explicit Session(boost::asio::io_context &ioc,
|
explicit Session(boost::asio::io_context &ioc,
|
||||||
boost::asio::ssl::context &ctx,
|
boost::asio::ssl::context &ctx,
|
||||||
std::unique_ptr<Listener> listener);
|
std::unique_ptr<Listener> listener,
|
||||||
|
std::shared_ptr<Logger> log_);
|
||||||
|
|
||||||
// Start the asynchronous operation
|
// Start the asynchronous operation
|
||||||
void run(std::string _host, std::string _port, std::string _path,
|
void run(std::string _host, std::string _port, std::string _path,
|
||||||
@@ -63,6 +66,7 @@ private:
|
|||||||
|
|
||||||
void checkKeepalive();
|
void checkKeepalive();
|
||||||
|
|
||||||
|
std::shared_ptr<Logger> log;
|
||||||
boost::asio::ip::tcp::resolver resolver;
|
boost::asio::ip::tcp::resolver resolver;
|
||||||
boost::beast::websocket::stream<
|
boost::beast::websocket::stream<
|
||||||
boost::beast::ssl_stream<boost::beast::tcp_stream>>
|
boost::beast::ssl_stream<boost::beast::tcp_stream>>
|
||||||
|
|||||||
Submodule
+1
Submodule lib/twitch-eventsub-ws/lib/fmt added at 123913715a
@@ -53,6 +53,7 @@ target_include_directories(${PROJECT_NAME}
|
|||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../include"
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../lib/date/include"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../lib/date/include"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../lib/fmt/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
|||||||
@@ -15,10 +15,26 @@
|
|||||||
#include <boost/json.hpp>
|
#include <boost/json.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#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 beast = boost::beast;
|
||||||
namespace http = beast::http;
|
namespace http = beast::http;
|
||||||
namespace websocket = beast::websocket;
|
namespace websocket = beast::websocket;
|
||||||
@@ -230,8 +246,10 @@ namespace {
|
|||||||
|
|
||||||
// Resolver and socket require an io_context
|
// Resolver and socket require an io_context
|
||||||
Session::Session(boost::asio::io_context &ioc, boost::asio::ssl::context &ctx,
|
Session::Session(boost::asio::io_context &ioc, boost::asio::ssl::context &ctx,
|
||||||
std::unique_ptr<Listener> listener)
|
std::unique_ptr<Listener> listener,
|
||||||
: resolver(boost::asio::make_strand(ioc))
|
std::shared_ptr<Logger> log_)
|
||||||
|
: log(std::move(log_))
|
||||||
|
, resolver(boost::asio::make_strand(ioc))
|
||||||
, ws(boost::asio::make_strand(ioc), ctx)
|
, ws(boost::asio::make_strand(ioc), ctx)
|
||||||
, listener(std::move(listener))
|
, 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)
|
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->ws.is_open() && this->listener)
|
||||||
{
|
{
|
||||||
if (this->keepaliveTimer)
|
if (this->keepaliveTimer)
|
||||||
@@ -505,7 +524,8 @@ boost::system::error_code Session::onSessionWelcome(
|
|||||||
this->keepaliveTimeout =
|
this->keepaliveTimeout =
|
||||||
std::chrono::seconds{payload.keepaliveTimeoutSeconds.value_or(60)} * 2;
|
std::chrono::seconds{payload.keepaliveTimeoutSeconds.value_or(60)} * 2;
|
||||||
assert(!this->keepaliveTimer);
|
assert(!this->keepaliveTimer);
|
||||||
std::cerr << "Keepalive: " << this->keepaliveTimeout.count() << 's';
|
this->log->debug(
|
||||||
|
c2fmt::format("Keepalive: {}s", this->keepaliveTimeout.count()));
|
||||||
this->checkKeepalive();
|
this->checkKeepalive();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@@ -551,7 +571,7 @@ void Session::checkKeepalive()
|
|||||||
{
|
{
|
||||||
if (!this->receivedMessage)
|
if (!this->receivedMessage)
|
||||||
{
|
{
|
||||||
std::cerr << "Keepalive timeout, closing\n";
|
this->log->debug("Keepalive timeout, closing");
|
||||||
if (this->listener)
|
if (this->listener)
|
||||||
{
|
{
|
||||||
this->listener->onClose(std::move(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) {
|
this->keepaliveTimer->async_wait([this](boost::system::error_code ec) {
|
||||||
if (ec)
|
if (ec)
|
||||||
{
|
{
|
||||||
std::cerr << "Keepalive timer cancelled: " << ec.message() << '\n';
|
this->log->warn(
|
||||||
|
c2fmt::format("Keepalive timer cancelled: {}", ec.message()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->checkKeepalive();
|
this->checkKeepalive();
|
||||||
|
|||||||
@@ -153,11 +153,12 @@ TEST_P(TestHandleMessageP, Run)
|
|||||||
{
|
{
|
||||||
auto buf = readToFlatBuffer(filePath(GetParam() + ".json"));
|
auto buf = readToFlatBuffer(filePath(GetParam() + ".json"));
|
||||||
|
|
||||||
|
auto log = std::make_shared<NullLogger>();
|
||||||
std::unique_ptr<Listener> listener = std::make_unique<NoOpListener>();
|
std::unique_ptr<Listener> listener = std::make_unique<NoOpListener>();
|
||||||
boost::asio::io_context ioc;
|
boost::asio::io_context ioc;
|
||||||
boost::asio::ssl::context ssl(
|
boost::asio::ssl::context ssl(
|
||||||
boost::asio::ssl::context::method::tls_client);
|
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);
|
auto ec = sess->handleMessage(buf);
|
||||||
ASSERT_FALSE(ec.failed())
|
ASSERT_FALSE(ec.failed())
|
||||||
<< ec.what() << ec.message() << ec.location().to_string();
|
<< ec.what() << ec.message() << ec.location().to_string();
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -40,8 +40,35 @@ const auto &LOG = chatterinoTwitchEventSub;
|
|||||||
|
|
||||||
namespace chatterino::eventsub {
|
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()
|
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(),
|
.arg(Version::instance().version(),
|
||||||
Version::instance().commitHash())
|
Version::instance().commitHash())
|
||||||
.toUtf8()
|
.toUtf8()
|
||||||
@@ -456,7 +483,7 @@ void Controller::createConnection(std::string host, std::string port,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto connection = std::make_shared<lib::Session>(
|
auto connection = std::make_shared<lib::Session>(
|
||||||
this->ioContext, sslContext, std::move(listener));
|
this->ioContext, sslContext, std::move(listener), this->logProxy);
|
||||||
|
|
||||||
this->registerConnection(connection);
|
this->registerConnection(connection);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "providers/twitch/eventsub/SubscriptionHandle.hpp"
|
#include "providers/twitch/eventsub/SubscriptionHandle.hpp"
|
||||||
#include "providers/twitch/eventsub/SubscriptionRequest.hpp"
|
#include "providers/twitch/eventsub/SubscriptionRequest.hpp"
|
||||||
|
#include "twitch-eventsub-ws/logger.hpp"
|
||||||
#include "twitch-eventsub-ws/session.hpp"
|
#include "twitch-eventsub-ws/session.hpp"
|
||||||
#include "util/ExponentialBackoff.hpp"
|
#include "util/ExponentialBackoff.hpp"
|
||||||
#include "util/ThreadGuard.hpp"
|
#include "util/ThreadGuard.hpp"
|
||||||
@@ -91,6 +92,8 @@ private:
|
|||||||
|
|
||||||
void clearConnections();
|
void clearConnections();
|
||||||
|
|
||||||
|
std::shared_ptr<lib::Logger> logProxy;
|
||||||
|
|
||||||
const std::string userAgent;
|
const std::string userAgent;
|
||||||
|
|
||||||
std::string eventSubHost;
|
std::string eventSubHost;
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ AboutPage::AboutPage()
|
|||||||
addLicense(form.getElement(), "Howard Hinnant's date.h",
|
addLicense(form.getElement(), "Howard Hinnant's date.h",
|
||||||
"https://github.com/HowardHinnant/date",
|
"https://github.com/HowardHinnant/date",
|
||||||
":/licenses/howard-hinnant-date.txt");
|
":/licenses/howard-hinnant-date.txt");
|
||||||
|
addLicense(form.getElement(), "{fmt}", "https://fmt.dev",
|
||||||
|
":/licenses/fmtlib.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attributions
|
// Attributions
|
||||||
|
|||||||
@@ -304,13 +304,14 @@ TEST_P(TestEventSubMessagesP, Run)
|
|||||||
input = snapshot->input().toArray();
|
input = snapshot->input().toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto log = std::make_shared<eventsub::lib::NullLogger>();
|
||||||
std::unique_ptr<eventsub::lib::Listener> listener =
|
std::unique_ptr<eventsub::lib::Listener> listener =
|
||||||
std::make_unique<eventsub::Connection>();
|
std::make_unique<eventsub::Connection>();
|
||||||
boost::asio::io_context ioc;
|
boost::asio::io_context ioc;
|
||||||
boost::asio::ssl::context ssl(
|
boost::asio::ssl::context ssl(
|
||||||
boost::asio::ssl::context::method::tls_client);
|
boost::asio::ssl::context::method::tls_client);
|
||||||
auto sess =
|
auto sess = std::make_shared<eventsub::lib::Session>(
|
||||||
std::make_shared<eventsub::lib::Session>(ioc, ssl, std::move(listener));
|
ioc, ssl, std::move(listener), log);
|
||||||
|
|
||||||
for (const auto inputRef : input)
|
for (const auto inputRef : input)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user