From 448125f376f7f75d77d55dcfa33a8bcd734c07c1 Mon Sep 17 00:00:00 2001 From: Arun Date: Sat, 18 Jan 2025 17:45:38 -0800 Subject: [PATCH] fixing network log listener --- src/software/logger/BUILD | 3 ++ src/software/logger/network_logger.cpp | 45 ++++++++++++++++++++++ src/software/logger/network_logger.h | 45 +++------------------- src/software/network_log_listener_main.cpp | 21 ++++++++-- 4 files changed, 71 insertions(+), 43 deletions(-) create mode 100644 src/software/logger/network_logger.cpp diff --git a/src/software/logger/BUILD b/src/software/logger/BUILD index f50ed47a4b..969f9f672b 100644 --- a/src/software/logger/BUILD +++ b/src/software/logger/BUILD @@ -36,6 +36,9 @@ cc_library( hdrs = [ "network_logger.h", ], + srcs = [ + "network_logger.cpp", + ], deps = [ ":coloured_cout_sink", ":network_sink", diff --git a/src/software/logger/network_logger.cpp b/src/software/logger/network_logger.cpp new file mode 100644 index 0000000000..02ed027d3d --- /dev/null +++ b/src/software/logger/network_logger.cpp @@ -0,0 +1,45 @@ +#include "software/logger/network_logger.h" + +#include "software/logger/csv_sink.h" +#include "software/logger/plotjuggler_sink.h" + +std::shared_ptr NetworkLoggerSingleton::instance; + +NetworkLoggerSingleton::NetworkLoggerSingleton(int robot_id, bool enable_log_merging) +{ + logWorker = g3::LogWorker::createLogWorker(); + + network_sink_handle = logWorker->addSink(std::make_unique(robot_id, enable_log_merging), + &NetworkSink::sendToNetwork); + + // Sink for outputting logs to the terminal + auto colour_cout_sink_handle = + logWorker->addSink(std::make_unique(true), + &ColouredCoutSink::displayColouredLog); + + auto csv_sink_handle = logWorker->addSink(std::make_unique(CSV_PATH), + &CSVSink::appendToFile); + + // Sink for PlotJuggler plotting + auto plotjuggler_handle = logWorker->addSink(std::make_unique(), + &PlotJugglerSink::sendToPlotJuggler); + + g3::initializeLogging(logWorker.get()); +} + +void NetworkLoggerSingleton::initializeLogger(int robot_id, bool enable_log_merging) +{ + if (!instance) + { + instance = std::make_shared(robot_id, enable_log_merging); + } +} + +void NetworkLoggerSingleton::replaceUdpSender(std::shared_ptr> new_sender) +{ + if (!instance) + { + return; + } + instance->network_sink_handle->call(&NetworkSink::replaceUdpSender, new_sender); +} diff --git a/src/software/logger/network_logger.h b/src/software/logger/network_logger.h index 1659c41f5c..755108ff26 100644 --- a/src/software/logger/network_logger.h +++ b/src/software/logger/network_logger.h @@ -20,52 +20,19 @@ class NetworkLoggerSingleton * Initializes a g3log logger for the calling program. This should only be * called once at the start of a program. */ - static void initializeLogger(int robot_id, bool enable_log_merging) - { - NetworkLogger(); - } + static void initializeLogger(int robot_id, bool enable_log_merging); /** * Updates the underlying UDP sender associated with this network sink. Useful when a new FullSystem is connected. + * + * @param new_sender the new UDP sender to use */ - static void replaceUdpSender(std::shared_ptr> new_sender) - { - std::shared_ptr logger = NetworkLogger(); - if (!logger) - { - return; - } - logger->network_sink_handle->call(&NetworkSink::replaceUdpSender, new_sender); - } + static void replaceUdpSender(std::shared_ptr> new_sender); private: - static std::shared_ptr NetworkLogger() - { - static std::shared_ptr s(new NetworkLoggerSingleton(robot_id, enable_log_merging)); - return s; - } + NetworkLoggerSingleton(int robot_id, bool enable_log_merging); - NetworkLoggerSingleton(int robot_id, bool enable_log_merging) - { - logWorker = g3::LogWorker::createLogWorker(); - - network_sink_handle = logWorker->addSink(std::make_unique(robot_id, enable_log_merging), - &NetworkSink::sendToNetwork); - - // Sink for outputting logs to the terminal - auto colour_cout_sink_handle = - logWorker->addSink(std::make_unique(true), - &ColouredCoutSink::displayColouredLog); - - auto csv_sink_handle = logWorker->addSink(std::make_unique(CSV_PATH), - &CSVSink::appendToFile); - - // Sink for PlotJuggler plotting - auto plotjuggler_handle = logWorker->addSink(std::make_unique(), - &PlotJugglerSink::sendToPlotJuggler); - - g3::initializeLogging(logWorker.get()); - } + static std::shared_ptr instance; std::unique_ptr logWorker; std::unique_ptr> network_sink_handle; diff --git a/src/software/network_log_listener_main.cpp b/src/software/network_log_listener_main.cpp index 55edb5e92e..4b135391a7 100644 --- a/src/software/network_log_listener_main.cpp +++ b/src/software/network_log_listener_main.cpp @@ -8,6 +8,15 @@ #include "shared/constants.h" #include "software/networking/udp/threaded_proto_udp_listener.hpp" +class RobotLogListenerWrapper +{ + private: + std::mutex m; + std::optional>> listener; +}; + +std::unordered_map robot_log_listeners; + /* * This standalone program listens for RobotLog protos on the specified ip address * and logs them @@ -43,7 +52,7 @@ int main(int argc, char **argv) { bool help = false; std::string interface = ""; - int channel = 0; + std::string robot_ip_address = ""; std::vector selected_ids = {}; }; @@ -55,11 +64,9 @@ int main(int argc, char **argv) desc.add_options()("interface", boost::program_options::value(&args.interface), "Network interface to listen for robot logs from"); - desc.add_options()("channel", boost::program_options::value(&args.channel), - "Multicast channel to listen for robot logs on"); desc.add_options()( "selected_ids", - boost::program_options::value>(&args.selected_ids)->multitoken(), + boost::program_options::value>(&args.selected_ids)->multitoken(), "Space separated robot IDs to show logs from. If not specified, logs from all robots will be shown"); boost::program_options::variables_map vm; @@ -82,6 +89,12 @@ int main(int argc, char **argv) LOG(FATAL) << "A network interface must be specified to listen on!"; } + std::optional local_ip = getLocalIp(args.interface); + if (!local_ip) + { + LOG(FATAL) << "Could not get local IP address for interface: " << args.interface; + } + // Only show logs from robots in the selected_ids list, unless it is empty auto robot_log_callback = [args](TbotsProto::RobotLog log) { if (!args.selected_ids.empty() &&