mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-11-07 06:39:10 +08:00
[refactor] use MiniRTC public APIs across clients
This commit is contained in:
@@ -1,19 +1,22 @@
|
||||
#include "controller_diagnostics.h"
|
||||
#include <log.h>
|
||||
#include <minirtc.h>
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
|
||||
namespace crossdesk {
|
||||
namespace {
|
||||
// Signaling errors and SDP can contain credentials. Only audited transport
|
||||
// events reach this sink; arbitrary MiniRTC messages remain suppressed.
|
||||
std::string DiagnosticEvent(const spdlog::details::log_msg &message) {
|
||||
std::string_view source = message.source.filename ? message.source.filename : "";
|
||||
std::string DiagnosticEvent(const MiniRtcLogRecord &message) {
|
||||
std::string_view source = message.source_file ? message.source_file : "";
|
||||
const auto slash = source.find_last_of("/\\");
|
||||
if (slash != std::string_view::npos)
|
||||
source.remove_prefix(slash + 1);
|
||||
const std::string_view text(message.payload.data(), message.payload.size());
|
||||
if (source == "controller_session.cpp")
|
||||
return std::string(text); // Local states/counters only at these call sites.
|
||||
const std::string_view text(message.message, message.message_size);
|
||||
if (source == "ws_client.cpp") {
|
||||
if (text == "WebSocket connection opened") return std::string(text);
|
||||
// These call sites contain library category names, numeric codes and retry
|
||||
@@ -59,30 +62,56 @@ std::string DiagnosticEvent(const spdlog::details::log_msg &message) {
|
||||
return {};
|
||||
}
|
||||
|
||||
class DiagnosticSink final : public spdlog::sinks::base_sink<std::mutex> {
|
||||
class DiagnosticWriter {
|
||||
public:
|
||||
explicit DiagnosticSink(const std::string &directory)
|
||||
explicit DiagnosticWriter(const std::string &directory)
|
||||
: file_(directory + "/transport.log", 1024 * 1024, 2) {}
|
||||
|
||||
private:
|
||||
void sink_it_(const spdlog::details::log_msg &message) override {
|
||||
const auto event = DiagnosticEvent(message);
|
||||
if (event.empty())
|
||||
return;
|
||||
auto sanitized = message;
|
||||
sanitized.payload = spdlog::string_view_t(event.data(), event.size());
|
||||
file_.log(sanitized);
|
||||
void Write(const std::string &event, const MiniRtcLogRecord *record = nullptr) {
|
||||
if (event.empty()) return;
|
||||
spdlog::details::log_msg message("crossdesk", spdlog::level::info, event);
|
||||
if (record) {
|
||||
message.level = static_cast<spdlog::level::level_enum>(record->level);
|
||||
message.time = spdlog::log_clock::time_point(std::chrono::microseconds(record->timestamp_us));
|
||||
message.source = {record->source_file, record->source_line, ""};
|
||||
}
|
||||
file_.log(message);
|
||||
file_.flush();
|
||||
}
|
||||
void flush_() override { file_.flush(); }
|
||||
private:
|
||||
spdlog::sinks::rotating_file_sink_mt file_;
|
||||
};
|
||||
void ReceiveLog(const MiniRtcLogRecord *message, void *context) {
|
||||
if (message) static_cast<DiagnosticWriter *>(context)->Write(DiagnosticEvent(*message), message);
|
||||
}
|
||||
struct Diagnostics {
|
||||
std::mutex initialization, mutex;
|
||||
std::shared_ptr<DiagnosticWriter> writer;
|
||||
~Diagnostics() {
|
||||
// Quiesce the callback before releasing its application-owned context.
|
||||
ConfigureMiniRtcLogging(MiniRtcLogOff, nullptr, nullptr);
|
||||
}
|
||||
};
|
||||
Diagnostics &State() {
|
||||
static Diagnostics state;
|
||||
return state;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void InitializeControllerDiagnostics(const std::string &directory) {
|
||||
auto sink = std::make_shared<DiagnosticSink>(directory);
|
||||
minirtc::InitLogger(directory, std::move(sink));
|
||||
auto logger = minirtc::get_logger();
|
||||
logger->set_level(spdlog::level::info);
|
||||
auto &state = State();
|
||||
std::lock_guard initialize(state.initialization);
|
||||
auto writer = std::make_shared<DiagnosticWriter>(directory);
|
||||
if (ConfigureMiniRtcLogging(MiniRtcLogInfo, ReceiveLog, writer.get()) != 0)
|
||||
throw std::runtime_error("Unable to configure MiniRTC diagnostics");
|
||||
std::lock_guard lock(state.mutex);
|
||||
state.writer = std::move(writer);
|
||||
}
|
||||
void WriteControllerDiagnostic(const std::string &message) noexcept {
|
||||
try {
|
||||
auto &state = State();
|
||||
std::shared_ptr<DiagnosticWriter> writer;
|
||||
{ std::lock_guard lock(state.mutex); writer = state.writer; }
|
||||
if (writer) writer->Write(message);
|
||||
} catch (...) {}
|
||||
}
|
||||
} // namespace crossdesk
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <display_stream_id.h>
|
||||
#include <log.h>
|
||||
#include <preview_subscription.h>
|
||||
#include <stdexcept>
|
||||
#include <stream_names.h>
|
||||
@@ -159,7 +158,7 @@ void ControllerSession::Connect(SessionOptions options, std::string device,
|
||||
// Never register a desktop identity or persist local credentials.
|
||||
client_id_.clear();
|
||||
InitializeControllerDiagnostics(options_.log_directory);
|
||||
SPDLOG_LOGGER_INFO(minirtc::get_logger(), "Session registering");
|
||||
WriteControllerDiagnostic("Session registering");
|
||||
auto p = Parameters();
|
||||
peer_ = CreatePeer(&p);
|
||||
if (!peer_) {
|
||||
@@ -198,7 +197,7 @@ void ControllerSession::Tick() {
|
||||
if (Finished())
|
||||
break;
|
||||
if (e.kind == 0) {
|
||||
SPDLOG_LOGGER_INFO(minirtc::get_logger(), "Signal status: {}", e.code);
|
||||
WriteControllerDiagnostic("Signal status: " + std::to_string(e.code));
|
||||
if (e.code == SignalTlsCertError) {
|
||||
Fail("tls_certificate_error");
|
||||
break;
|
||||
@@ -210,8 +209,7 @@ void ControllerSession::Tick() {
|
||||
// The initial signaling transport can recover before a remote join is
|
||||
// sent. Keep its backoff worker alive within the original deadline.
|
||||
if (e.code == SignalReconnecting && state_ == "registering") {
|
||||
SPDLOG_LOGGER_INFO(minirtc::get_logger(),
|
||||
"Initial signaling retry within connection deadline");
|
||||
WriteControllerDiagnostic("Initial signaling retry within connection deadline");
|
||||
continue;
|
||||
}
|
||||
if (e.code == SignalClosed || e.code == SignalServerClosed ||
|
||||
@@ -236,8 +234,7 @@ void ControllerSession::Tick() {
|
||||
password_.clear();
|
||||
}
|
||||
} else if (e.kind == 1) {
|
||||
SPDLOG_LOGGER_INFO(minirtc::get_logger(), "Connection status: {} (session {})",
|
||||
e.code, state_);
|
||||
WriteControllerDiagnostic("Connection status: " + std::to_string(e.code) + " (session " + state_ + ")");
|
||||
if (e.code == ::Connected && !Connected()) {
|
||||
state_ = "connected";
|
||||
auto hello = MakeHostInformation("CrossDesk CLI", {}, false);
|
||||
@@ -365,8 +362,7 @@ void ControllerSession::ClosePeers() {
|
||||
password_.clear();
|
||||
}
|
||||
void ControllerSession::Fail(const char *reason) {
|
||||
SPDLOG_LOGGER_INFO(minirtc::get_logger(), "Session failed: {} (stage {})",
|
||||
reason, state_);
|
||||
WriteControllerDiagnostic("Session failed: " + std::string(reason) + " (stage " + state_ + ")");
|
||||
ReleaseInput();
|
||||
error_ = reason;
|
||||
state_ = "failed";
|
||||
@@ -449,7 +445,7 @@ void ControllerSession::Preview() {
|
||||
}
|
||||
void ControllerSession::SetControl(bool enabled) {
|
||||
if (control_ != enabled)
|
||||
SPDLOG_LOGGER_INFO(minirtc::get_logger(), "Remote control: {}", enabled);
|
||||
WriteControllerDiagnostic(std::string("Remote control: ") + (enabled ? "true" : "false"));
|
||||
if (!enabled)
|
||||
ReleaseInput();
|
||||
control_ = enabled;
|
||||
|
||||
Reference in New Issue
Block a user