diff --git a/.circleci/config.yml b/.circleci/config.yml index afcae4a..2930aff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,8 +36,6 @@ jobs: - run: name: "Test" command: cd build && ctest -C Release --output-on-failure && cd .. - environment: - SOCKET_LOG: debug - run: name: "Install" command: cmake --install build --config Release diff --git a/.github/workflows/PR.yml b/.github/workflows/PR.yml index 6be7374..a974478 100644 --- a/.github/workflows/PR.yml +++ b/.github/workflows/PR.yml @@ -25,8 +25,8 @@ jobs: - name: Install LLVM and Clang run: | - brew update - brew install llvm@17 + brew update || true + brew install llvm@17 || true - name: Install Rust toolchain uses: actions-rs/toolchain@v1 @@ -54,8 +54,6 @@ jobs: # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -C ${{env.BUILD_TYPE}} --output-on-failure - env: - SOCKET_LOG: debug - name: Install run: sudo cmake --install build --config Release diff --git a/.gitmodules b/.gitmodules index 98dca17..153978d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "concurrentqueue"] path = tests/concurrentqueue url = https://github.com/cameron314/concurrentqueue.git +[submodule "tests/spdlog"] + path = tests/spdlog-repo + url = https://github.com/gabime/spdlog diff --git a/Cargo.toml b/Cargo.toml index 48a562d..a087ac9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,13 @@ edition = "2021" crate-type = ["staticlib"] [dependencies] -async-ringbuf = "0.2.0-rc.4" dashmap = { version = "5.4.0", features = ["inline"] } libc = "0.2.146" socket2 = "0.5.3" +[dependencies.async-ringbuf] +git = "https://github.com/Congyuwang/ringbuf.git" + [dependencies.tokio] version = "1.29.1" default-features = false @@ -31,4 +33,4 @@ features = ["std"] [dependencies.tracing-subscriber] version = "0.3.17" default-features = false -features = ["std", "fmt", "env-filter"] +features = ["std", "fmt", "env-filter", "registry"] diff --git a/examples/echo_server/justfile b/examples/echo_server/justfile index 7c5944c..6fb18b0 100644 --- a/examples/echo_server/justfile +++ b/examples/echo_server/justfile @@ -14,4 +14,4 @@ build: codesign -s - -v -f --entitlements debug.plist ./build/echo_server run: - SOCKET_LOG=info ./build/echo_server + ./build/echo_server diff --git a/include/socket_manager/socket_manager.h b/include/socket_manager/socket_manager.h index 83f278c..5150a2a 100644 --- a/include/socket_manager/socket_manager.h +++ b/include/socket_manager/socket_manager.h @@ -7,9 +7,39 @@ #include #include #include +#include namespace socket_manager { +/** + * @brief The log data structure. + * + * This structure is used to pass log data from C to C++. + */ +struct LogData { + SOCKET_MANAGER_C_API_TraceLevel level; + std::string_view target; + std::string_view file; + std::string_view message; +}; + +/** + * Helper function to convert from C log data to C++ log data. + */ +LogData from_c_log_data(SOCKET_MANAGER_C_API_LogData log_data); + +/** + * @brief Initialize the logger for the socket manager. + * + * This function cannot be called more than once, + * otherwise it will throw an exception.. + * + * Tracer must be thread safe (as most loggers are thread safe). + */ +void init_logger(void (*tracer)(SOCKET_MANAGER_C_API_LogData), + SOCKET_MANAGER_C_API_TraceLevel tracer_max_level, + SOCKET_MANAGER_C_API_TraceLevel log_print_level); + /** * @brief Manages a set of sockets. * diff --git a/include/socket_manager_c_api.h b/include/socket_manager_c_api.h index 08575f7..a1cfa0d 100644 --- a/include/socket_manager_c_api.h +++ b/include/socket_manager_c_api.h @@ -15,6 +15,48 @@ enum class SOCKET_MANAGER_C_API_ConnStateCode { ConnectError = 3, }; +/** + * Trace Level + */ +enum class SOCKET_MANAGER_C_API_TraceLevel { + /** + * The "trace" level. + * + * Designates very low priority, often extremely verbose, information. + */ + Trace = 0, + /** + * The "debug" level. + * + * Designates lower priority information. + */ + Debug = 1, + /** + * The "info" level. + * + * Designates useful information. + */ + Info = 2, + /** + * The "warn" level. + * + * Designates hazardous situations. + */ + Warn = 3, + /** + * The "error" level. + * + * Designates very serious errors. + */ + Error = 4, + /** + * Turn off all levels. + * + * Disable log output. + */ + Off = 5, +}; + struct SOCKET_MANAGER_C_API_Connection; /** @@ -158,6 +200,22 @@ struct SOCKET_MANAGER_C_API_ConnMsg { size_t Len; }; +/** + * Log Data + */ +struct SOCKET_MANAGER_C_API_LogData { + SOCKET_MANAGER_C_API_TraceLevel Level; + const char *Target; + size_t TargetN; + const char *File; + size_t FileN; + /** + * The `message` pointer is only valid for the duration of the callback. + */ + const char *Message; + size_t MessageN; +}; + extern "C" { /** @@ -463,6 +521,19 @@ int socket_manager_join(SOCKET_MANAGER_C_API_SocketManager *manager, char **err) */ void socket_manager_free(SOCKET_MANAGER_C_API_SocketManager *manager); +/** + * Init logger. + * + * # Arguments + * - `tracer`: The tracer object. + * - `tracer_max_level`: The max level of the tracer. + * - `log_print_level`: The level of the log to print. + */ +void socket_manager_logger_init(void (*tracer)(SOCKET_MANAGER_C_API_LogData), + SOCKET_MANAGER_C_API_TraceLevel tracer_max_level, + SOCKET_MANAGER_C_API_TraceLevel log_print_level, + char **err); + } // extern "C" #endif // SOCKET_MANAGER_C_API_H diff --git a/justfile b/justfile index 12c6386..559ac6c 100644 --- a/justfile +++ b/justfile @@ -15,8 +15,7 @@ dev-docker: docker build -f ./dockerfile/dev-containers/jammy/Dockerfile -t congyuwang/socket-manager-dev:jammy . test: - cd build && SOCKET_LOG=debug ctest --output-on-failure && cd .. - + cd build && ctest --output-on-failure && cd .. time: /usr/bin/time -l -h -p ./build/tests/CommonCxxTests test_transfer_data_large /usr/bin/time -l -h -p ./build/tests/CommonCxxTests test_transfer_data_large_async diff --git a/socket_manager/socket_manager.cc b/socket_manager/socket_manager.cc index 63efe51..456f0ee 100644 --- a/socket_manager/socket_manager.cc +++ b/socket_manager/socket_manager.cc @@ -1,7 +1,30 @@ #include "socket_manager/socket_manager.h" +#include "socket_manager_c_api.h" +#include namespace socket_manager { +LogData from_c_log_data(SOCKET_MANAGER_C_API_LogData log_data) { + return { + log_data.Level, + std::string_view(log_data.Target, log_data.TargetN), + std::string_view(log_data.File, log_data.FileN), + std::string_view(log_data.Message, log_data.MessageN), + }; +} + +void init_logger(void (*tracer)(SOCKET_MANAGER_C_API_LogData), + SOCKET_MANAGER_C_API_TraceLevel tracer_max_level, + SOCKET_MANAGER_C_API_TraceLevel log_print_level) { + char *err = nullptr; + socket_manager_logger_init(tracer, tracer_max_level, log_print_level, &err); + if (err != nullptr) { + const std::string err_str(err); + free(err); + throw std::runtime_error(err_str); + } +} + SocketManager::SocketManager(const std::shared_ptr &conn_cb, size_t n_threads) : conn_cb(conn_cb) { diff --git a/src/c_api/mod.rs b/src/c_api/mod.rs index 09d0318..2375954 100644 --- a/src/c_api/mod.rs +++ b/src/c_api/mod.rs @@ -5,4 +5,5 @@ mod msg_sender; pub(crate) mod on_conn; pub(crate) mod on_msg; mod socket_manager; +pub(crate) mod tracer; mod utils; diff --git a/src/c_api/tracer.rs b/src/c_api/tracer.rs new file mode 100644 index 0000000..3b43a61 --- /dev/null +++ b/src/c_api/tracer.rs @@ -0,0 +1,144 @@ +//! Define a layer to pass log message to foreign interface. +use super::utils::write_error_c_str; +use crate::init_logger; +use libc::size_t; +use std::{ffi::c_char, fmt, ptr::null_mut}; +use tracing::{field::Field, Level}; +use tracing_subscriber::{filter::LevelFilter, Layer}; + +const MESSAGE: &str = "message"; +const EMPTY: &str = ""; + +/// Trace Level +#[repr(C)] +pub enum TraceLevel { + /// The "trace" level. + /// + /// Designates very low priority, often extremely verbose, information. + Trace = 0, + /// The "debug" level. + /// + /// Designates lower priority information. + Debug = 1, + /// The "info" level. + /// + /// Designates useful information. + Info = 2, + /// The "warn" level. + /// + /// Designates hazardous situations. + Warn = 3, + /// The "error" level. + /// + /// Designates very serious errors. + Error = 4, + /// Turn off all levels. + /// + /// Disable log output. + Off = 5, +} + +/// Log Data +#[repr(C)] +pub struct LogData { + pub level: TraceLevel, + pub target: *const c_char, + pub target_n: size_t, + pub file: *const c_char, + pub file_n: size_t, + /// The `message` pointer is only valid for the duration of the callback. + pub message: *const c_char, + pub message_n: size_t, +} + +/// Init logger. +/// +/// # Arguments +/// - `tracer`: The tracer object. +/// - `tracer_max_level`: The max level of the tracer. +/// - `log_print_level`: The level of the log to print. +#[no_mangle] +pub unsafe extern "C" fn socket_manager_logger_init( + tracer: unsafe extern "C" fn(LogData) -> (), + tracer_max_level: TraceLevel, + log_print_level: TraceLevel, + err: *mut *mut c_char, +) { + let foreign_logger = ForeignLogger(tracer).with_filter(tracer_max_level.into()); + match init_logger(log_print_level.into(), foreign_logger) { + Ok(_) => *err = null_mut(), + Err(e) => write_error_c_str(e, err), + } +} + +pub struct ForeignLogger(unsafe extern "C" fn(LogData) -> ()); + +impl Layer for ForeignLogger +where + S: tracing::Subscriber, +{ + fn on_event( + &self, + event: &tracing::Event<'_>, + _ctx: tracing_subscriber::layer::Context<'_, S>, + ) { + let mut get_msg = GetMsgVisitor(None); + event.record(&mut get_msg); + let file = if let (Some(f), Some(l)) = (event.metadata().file(), event.metadata().line()) { + format!("{}:{}", f, l) + } else { + String::new() + }; + let data = LogData { + level: event.metadata().level().into(), + target: event.metadata().target().as_ptr() as *const c_char, + target_n: event.metadata().target().len(), + file: file.as_ptr() as *const c_char, + file_n: file.len(), + message: get_msg + .0 + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(EMPTY.as_ptr()) as *const c_char, + message_n: get_msg.0.as_ref().map(|s| s.len()).unwrap_or(0), + }; + unsafe { self.0(data) } + } +} + +// Helper methods and structs. + +struct GetMsgVisitor(Option); + +impl tracing::field::Visit for GetMsgVisitor { + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + if field.name() == MESSAGE { + self.0 = Some(format!("{:?}", value)); + } + } +} + +impl Into for TraceLevel { + fn into(self) -> LevelFilter { + match self { + TraceLevel::Trace => LevelFilter::TRACE, + TraceLevel::Debug => LevelFilter::DEBUG, + TraceLevel::Info => LevelFilter::INFO, + TraceLevel::Warn => LevelFilter::WARN, + TraceLevel::Error => LevelFilter::ERROR, + TraceLevel::Off => LevelFilter::OFF, + } + } +} + +impl From<&Level> for TraceLevel { + fn from(value: &Level) -> Self { + match *value { + Level::TRACE => TraceLevel::Trace, + Level::DEBUG => TraceLevel::Debug, + Level::INFO => TraceLevel::Info, + Level::WARN => TraceLevel::Warn, + Level::ERROR => TraceLevel::Error, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 34a640a..ea9580b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ mod read; mod utils; mod write; +use c_api::tracer::ForeignLogger; use dashmap::DashMap; use std::net::SocketAddr; use std::sync::atomic::{AtomicBool, Ordering}; @@ -23,12 +24,15 @@ use tokio::net::{TcpListener, TcpStream}; use tokio::runtime::Handle; use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; use tokio::sync::{mpsc, oneshot}; -use tracing_subscriber::EnvFilter; +use tracing_subscriber::filter::{Filtered, LevelFilter}; +use tracing_subscriber::util::{SubscriberInitExt, TryInitError}; +use tracing_subscriber::Layer; +use tracing_subscriber::{prelude::*, Registry}; +pub use c_api::tracer::TraceLevel; pub use conn::*; pub use msg_sender::*; -const SOCKET_LOG: &str = "SOCKET_LOG"; const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5); /// The Main Struct of the Library. @@ -104,6 +108,23 @@ impl ConnectionState { } } +/// Initialize socket manager logger. +/// Call this before anything else to prevent missing info. +/// This cannot be called twice, even accross multiple socket_manager instances. +pub fn init_logger( + log_print_level: LevelFilter, + foreign_logger: Filtered, +) -> Result<(), TryInitError> { + let fmt_layer = { + let fmt = tracing_subscriber::fmt::layer(); + fmt.with_filter(log_print_level) + }; + tracing_subscriber::registry() + .with(foreign_logger) + .with(fmt_layer) + .try_init() +} + /// Msg struct for the on_msg callback. pub struct Msg<'a> { bytes: &'a [u8], @@ -125,13 +146,6 @@ impl SocketManager { on_conn: OnConn, n_threads: usize, ) -> std::io::Result { - let _ = tracing_subscriber::fmt() - .with_env_filter( - EnvFilter::builder() - .with_env_var(SOCKET_LOG) - .from_env_lossy(), - ) - .try_init(); let runtime = utils::start_runtime(n_threads)?; let (cmd_send, cmd_recv) = mpsc::unbounded_channel::(); let connection_state = ConnectionState::new(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 57ef01a..f8585c6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,8 +17,9 @@ create_test_sourcelist(Tests CommonCxxTests.cxx ${test_files}) # build test driver add_executable(CommonCxxTests ${Tests}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/spdlog-repo/include/) target_link_libraries(CommonCxxTests - PUBLIC + PRIVATE socket_manager ${CMAKE_THREAD_LIBS_INIT}) diff --git a/tests/spdlog-repo b/tests/spdlog-repo new file mode 160000 index 0000000..ff205fd --- /dev/null +++ b/tests/spdlog-repo @@ -0,0 +1 @@ +Subproject commit ff205fd29a4a2f6ebcbecffd149153256d89a671 diff --git a/tests/test_abort_join.cpp b/tests/test_abort_join.cpp index c0a185e..39409d8 100644 --- a/tests/test_abort_join.cpp +++ b/tests/test_abort_join.cpp @@ -7,6 +7,7 @@ using namespace socket_manager; void abort_manager(SocketManager &manager) { manager.abort(); } int test_abort_join(int argc, char **argv) { + SpdLogger::init(); auto nothing_cb = std::make_shared(); SocketManager nothing(nothing_cb); diff --git a/tests/test_auto_flush.cpp b/tests/test_auto_flush.cpp index 8a4e61e..2ef88ce 100644 --- a/tests/test_auto_flush.cpp +++ b/tests/test_auto_flush.cpp @@ -64,6 +64,7 @@ class SendHelloWorldDoNotClose : public DoNothingConnCallback { }; int test_auto_flush(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40101"; auto send_cb = std::make_shared(); diff --git a/tests/test_bad_address_connect.cpp b/tests/test_bad_address_connect.cpp index 70a3bb6..c8638ea 100644 --- a/tests/test_bad_address_connect.cpp +++ b/tests/test_bad_address_connect.cpp @@ -4,6 +4,7 @@ using namespace socket_manager; int test_bad_address_connect(int argc, char **argv) { + SpdLogger::init(); auto nothing_cb = std::make_shared(); SocketManager nothing(nothing_cb); try { diff --git a/tests/test_bad_address_listen.cpp b/tests/test_bad_address_listen.cpp index 9643b07..02b1623 100644 --- a/tests/test_bad_address_listen.cpp +++ b/tests/test_bad_address_listen.cpp @@ -4,6 +4,7 @@ using namespace socket_manager; int test_bad_address_listen(int argc, char **argv) { + SpdLogger::init(); auto nothing_cb = std::make_shared(); SocketManager nothing(nothing_cb); try { diff --git a/tests/test_callback_throw_error.cpp b/tests/test_callback_throw_error.cpp index d9e1e00..1e9f7a0 100644 --- a/tests/test_callback_throw_error.cpp +++ b/tests/test_callback_throw_error.cpp @@ -75,6 +75,7 @@ class StoreAllEventsConnHelloCallback : public StoreAllEventsConnCallback { }; int test_callback_throw_error(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40102"; auto err_before_cb = std::make_shared(); diff --git a/tests/test_drop_sender.cpp b/tests/test_drop_sender.cpp index 40db611..5586851 100644 --- a/tests/test_drop_sender.cpp +++ b/tests/test_drop_sender.cpp @@ -6,6 +6,7 @@ // this test is to test that dropping sender object closes remote connections int test_drop_sender(int argc, char **argv) { + SpdLogger::init(); const std::string local_addr = "127.0.0.1:40100"; auto lock = std::make_shared(); diff --git a/tests/test_error_call_after_abort.cpp b/tests/test_error_call_after_abort.cpp index 076c2c9..53715f5 100644 --- a/tests/test_error_call_after_abort.cpp +++ b/tests/test_error_call_after_abort.cpp @@ -4,6 +4,7 @@ using namespace socket_manager; int test_error_call_after_abort(int argc, char **argv) { + SpdLogger::init(); auto nothing_cb = std::make_shared(); SocketManager nothing(nothing_cb); diff --git a/tests/test_error_connect.cpp b/tests/test_error_connect.cpp index aa828db..9c6d2f8 100644 --- a/tests/test_error_connect.cpp +++ b/tests/test_error_connect.cpp @@ -3,6 +3,7 @@ #include int test_error_connect(int argc, char **argv) { + SpdLogger::init(); auto lock = std::make_shared(); auto cond = std::make_shared(); auto sig = std::make_shared(0); diff --git a/tests/test_error_listen.cpp b/tests/test_error_listen.cpp index 3116fb1..62e035b 100644 --- a/tests/test_error_listen.cpp +++ b/tests/test_error_listen.cpp @@ -3,6 +3,7 @@ #include int test_error_listen(int argc, char **argv) { + SpdLogger::init(); auto lock = std::make_shared(); auto cond = std::make_shared(); auto sig = std::make_shared(0); diff --git a/tests/test_error_send_after_closed.cpp b/tests/test_error_send_after_closed.cpp index 88f1567..cdcecf2 100644 --- a/tests/test_error_send_after_closed.cpp +++ b/tests/test_error_send_after_closed.cpp @@ -4,6 +4,7 @@ #include int test_error_send_after_closed(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40107"; auto server_cb = std::make_shared(); diff --git a/tests/test_error_twice_start.cpp b/tests/test_error_twice_start.cpp index e1a9f14..3f99613 100644 --- a/tests/test_error_twice_start.cpp +++ b/tests/test_error_twice_start.cpp @@ -52,6 +52,7 @@ class TwiceStartCallback : public ConnCallback { }; int test_error_twice_start(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40108"; auto bad_cb = std::make_shared(); diff --git a/tests/test_manual_flush.cpp b/tests/test_manual_flush.cpp index 9da6f6a..9002754 100644 --- a/tests/test_manual_flush.cpp +++ b/tests/test_manual_flush.cpp @@ -126,6 +126,7 @@ class EchoCallback : public ConnCallback { }; int test_manual_flush(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40201"; diff --git a/tests/test_multiple_connections.cpp b/tests/test_multiple_connections.cpp index 546b196..0c14bed 100644 --- a/tests/test_multiple_connections.cpp +++ b/tests/test_multiple_connections.cpp @@ -4,6 +4,7 @@ #include int test_multiple_connections(int argc, char **argv) { + SpdLogger::init(); // establish 3 connections from p0 (client) -> p1 (server) port 0 // and 2 connections from p0 (client) -> p1 (server) port 1 diff --git a/tests/test_transfer_data_large_async.cpp b/tests/test_transfer_data_large_async.cpp index 6da270e..f6005c0 100644 --- a/tests/test_transfer_data_large_async.cpp +++ b/tests/test_transfer_data_large_async.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_large_async(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(SMALL_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_large_block.cpp b/tests/test_transfer_data_large_block.cpp index f98c87a..b0c5ef6 100644 --- a/tests/test_transfer_data_large_block.cpp +++ b/tests/test_transfer_data_large_block.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_large_block(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(LARGE_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_large_no_flush.cpp b/tests/test_transfer_data_large_no_flush.cpp index 1b1f619..31f9ac8 100644 --- a/tests/test_transfer_data_large_no_flush.cpp +++ b/tests/test_transfer_data_large_no_flush.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_large_no_flush(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(LARGE_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_large_nonblock.cpp b/tests/test_transfer_data_large_nonblock.cpp index 40ca58a..2fa4b76 100644 --- a/tests/test_transfer_data_large_nonblock.cpp +++ b/tests/test_transfer_data_large_nonblock.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_large_nonblock(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(LARGE_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_mid_async.cpp b/tests/test_transfer_data_mid_async.cpp index 2efc039..72277b5 100644 --- a/tests/test_transfer_data_mid_async.cpp +++ b/tests/test_transfer_data_mid_async.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_mid_async(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(MID_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_mid_block.cpp b/tests/test_transfer_data_mid_block.cpp index 1102e00..c3f00ca 100644 --- a/tests/test_transfer_data_mid_block.cpp +++ b/tests/test_transfer_data_mid_block.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_mid_block(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(MID_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_mid_no_flush.cpp b/tests/test_transfer_data_mid_no_flush.cpp index 94dc8fe..24e6356 100644 --- a/tests/test_transfer_data_mid_no_flush.cpp +++ b/tests/test_transfer_data_mid_no_flush.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_mid_no_flush(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(MID_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_mid_nonblock.cpp b/tests/test_transfer_data_mid_nonblock.cpp index 69a60e4..a5914f1 100644 --- a/tests/test_transfer_data_mid_nonblock.cpp +++ b/tests/test_transfer_data_mid_nonblock.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_mid_nonblock(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(MID_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_small_async.cpp b/tests/test_transfer_data_small_async.cpp index fd18965..81185a8 100644 --- a/tests/test_transfer_data_small_async.cpp +++ b/tests/test_transfer_data_small_async.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_small_async(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(SMALL_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_small_block.cpp b/tests/test_transfer_data_small_block.cpp index 07a1485..2c535c8 100644 --- a/tests/test_transfer_data_small_block.cpp +++ b/tests/test_transfer_data_small_block.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_small_block(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(SMALL_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_small_no_flush.cpp b/tests/test_transfer_data_small_no_flush.cpp index b367569..6ea982c 100644 --- a/tests/test_transfer_data_small_no_flush.cpp +++ b/tests/test_transfer_data_small_no_flush.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_small_no_flush(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(SMALL_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_transfer_data_small_nonblock.cpp b/tests/test_transfer_data_small_nonblock.cpp index 081336f..90eeeaa 100644 --- a/tests/test_transfer_data_small_nonblock.cpp +++ b/tests/test_transfer_data_small_nonblock.cpp @@ -5,6 +5,7 @@ #include int test_transfer_data_small_nonblock(int argc, char **argv) { + SpdLogger::init(); const std::string addr = "127.0.0.1:40013"; auto send_cb = std::make_shared(SMALL_MSG_SIZE, TOTAL_SIZE); diff --git a/tests/test_utils.h b/tests/test_utils.h index d0f239a..40b2b94 100644 --- a/tests/test_utils.h +++ b/tests/test_utils.h @@ -1,7 +1,9 @@ +#include "spdlog/common.h" #undef NDEBUG #ifndef SOCKET_MANAGER_TEST_UTILS_H #define SOCKET_MANAGER_TEST_UTILS_H +#include "spdlog/spdlog.h" #include #include #include @@ -11,6 +13,71 @@ #include #include +class SpdLogger { +public: + static void init(SOCKET_MANAGER_C_API_TraceLevel level = + SOCKET_MANAGER_C_API_TraceLevel::Debug) { + switch (level) { + case SOCKET_MANAGER_C_API_TraceLevel::Trace: { + spdlog::set_level(spdlog::level::trace); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Debug: { + spdlog::set_level(spdlog::level::debug); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Info: { + spdlog::set_level(spdlog::level::info); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Warn: { + spdlog::set_level(spdlog::level::warn); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Error: { + spdlog::set_level(spdlog::level::err); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Off: { + spdlog::set_level(spdlog::level::off); + break; + } + } + socket_manager::init_logger(print_log, level, + SOCKET_MANAGER_C_API_TraceLevel::Off); + }; + +private: + static void print_log(SOCKET_MANAGER_C_API_LogData log_data) { + socket_manager::LogData data = socket_manager::from_c_log_data(log_data); + switch (data.level) { + case SOCKET_MANAGER_C_API_TraceLevel::Trace: { + spdlog::trace("{}: {} {}", data.target, data.file, data.message); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Debug: { + spdlog::debug("{}: {} {}", data.target, data.file, data.message); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Info: { + spdlog::info("{}: {} {}", data.target, data.file, data.message); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Warn: { + spdlog::warn("{}: {} {}", data.target, data.file, data.message); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Error: { + spdlog::error("{}: {} {}", data.target, data.file, data.message); + break; + } + case SOCKET_MANAGER_C_API_TraceLevel::Off: { + break; + } + } + } +}; + using namespace socket_manager; const long long WAIT_MILLIS = 10;