From c5fd8a0b975b9a267981f0299b9d39a6eed39b3b Mon Sep 17 00:00:00 2001 From: Chris Love Date: Wed, 25 Aug 2021 20:32:35 -0700 Subject: [PATCH 01/11] Port code from prior PR (#1746), code cleanups --- example/example.cpp | 14 +++ include/spdlog/details/udp_client.h | 85 ++++++++++++++ include/spdlog/details/udp_client_windows.h | 117 ++++++++++++++++++++ include/spdlog/sinks/udp_sink.h | 87 +++++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 include/spdlog/details/udp_client.h create mode 100644 include/spdlog/details/udp_client_windows.h create mode 100644 include/spdlog/sinks/udp_sink.h diff --git a/example/example.cpp b/example/example.cpp index dea76f2f..7d7f9bf9 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -20,6 +20,7 @@ void user_defined_example(); void err_handler_example(); void syslog_example(); void custom_flags_example(); +void udp_example(); #include "spdlog/spdlog.h" #include "spdlog/cfg/env.h" // support for loading levels from the environment variable @@ -75,6 +76,7 @@ int main(int, char *[]) trace_example(); stopwatch_example(); custom_flags_example(); + udp_example(); // Flush all *registered* loggers using a worker thread every 3 seconds. // note: registered loggers *must* be thread safe for this to work correctly! @@ -198,6 +200,7 @@ void trace_example() // stopwatch example #include "spdlog/stopwatch.h" #include +#include "spdlog/sinks/udp_sink.h" void stopwatch_example() { spdlog::stopwatch sw; @@ -205,6 +208,17 @@ void stopwatch_example() spdlog::info("Stopwatch: {} seconds", sw); } +void udp_example() +{ + // using spdlog::details::make_unique; + //auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); + spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); + auto my_logger = spdlog::udp_logger_mt("udplog", cfg); + my_logger->set_level(spdlog::level::debug); + my_logger->info("hello world"); + my_logger->info("are you ok"); +} + // A logger with multiple sinks (stdout and file) - each with a different format and log level. void multi_sink_example() { diff --git a/include/spdlog/details/udp_client.h b/include/spdlog/details/udp_client.h new file mode 100644 index 00000000..13b608c8 --- /dev/null +++ b/include/spdlog/details/udp_client.h @@ -0,0 +1,85 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#ifdef _WIN32 +#error include udp_client-windows.h instead +#endif + +// udp client helper +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace spdlog { +namespace details { +class udp_client +{ + int socket_ = -1; + struct sockaddr_in sockAddr_; +public: + + bool init(const std::string &host, uint16_t port) + { + socket_ = socket(PF_INET, SOCK_DGRAM, 0); + if (socket_ < 0) + { + throw_spdlog_ex("error: Create Socket Failed!"); + return false; + } + + sockAddr_.sin_family = AF_INET; + sockAddr_.sin_port = htons(port); + inet_aton(host.c_str(), &sockAddr_.sin_addr); + + memset(sockAddr_.sin_zero, 0x00, sizeof(sockAddr_.sin_zero)); + return true; + } + + bool is_init() const + { + return socket_ != -1; + } + + void close() + { + if (is_init()) + { + ::close(socket_); + socket_ = -1; + } + } + + int fd() const + { + return socket_; + } + + ~udp_client() + { + close(); + } + + // Send exactly n_bytes of the given data. + // On error close the connection and throw. + void send(const char *data, size_t n_bytes) + { + ssize_t toslen = 0; + socklen_t tolen = sizeof(struct sockaddr); + if (( toslen = sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) == -1) + { + throw_spdlog_ex("sendto(2) failed", errno); + close(); + } + } +}; +} // namespace details +} // namespace spdlog \ No newline at end of file diff --git a/include/spdlog/details/udp_client_windows.h b/include/spdlog/details/udp_client_windows.h new file mode 100644 index 00000000..82d800a6 --- /dev/null +++ b/include/spdlog/details/udp_client_windows.h @@ -0,0 +1,117 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#define WIN32_LEAN_AND_MEAN +// tcp client helper +#include +#include + +#ifdef _WIN32 +#include +#include +#include +#include +#include +#include + +#pragma comment(lib, "Ws2_32.lib") +#pragma comment(lib, "Mswsock.lib") +#pragma comment(lib, "AdvApi32.lib") + +namespace spdlog { +namespace details { +class udp_client +{ + SOCKET socket_ = INVALID_SOCKET; + sockaddr_in addr_ = { 0 }; + + static bool winsock_initialized_() + { + SOCKET s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s == INVALID_SOCKET) + { + return false; + } + else + { + closesocket(s); + return true; + } + } + + static void init_winsock_() + { + WSADATA wsaData; + auto rv = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (rv != 0) + { + throw_winsock_error_("WSAStartup failed", ::WSAGetLastError()); + } + } + + static void throw_winsock_error_(const std::string &msg, int last_error) + { + char buf[512]; + ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL); + + throw_spdlog_ex(fmt::format("udp_sink - {}: {}", msg, buf)); + } + +public: + bool is_init() const + { + return socket_ != INVALID_SOCKET; + } + + bool init(const std::string &host, uint16_t port) + { + // initialize winsock if needed + if (!winsock_initialized_()) + { + init_winsock_(); + } + + if (is_init()) + { + close(); + } + + addr_.sin_family = AF_INET; + addr_.sin_port = htons(port); + InetPton(AF_INET, TEXT(host.c_str()), &addr_.sin_addr.s_addr); + return true; + } + + void close() + { + ::closesocket(socket_); + socket_ = INVALID_SOCKET; + WSACleanup(); + } + + SOCKET fd() const + { + return socket_; + } + + ~udp_client() + { + close(); + } + + void send(const char *data, size_t n_bytes) + { + if ((sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&addr_, sizeof(struct sockaddr))) == -1) + { + throw_spdlog_ex("sendto(2) failed", errno); + close(); + } + } +}; +} // namespace details +} // namespace spdlog + +#endif \ No newline at end of file diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h new file mode 100644 index 00000000..961d754d --- /dev/null +++ b/include/spdlog/sinks/udp_sink.h @@ -0,0 +1,87 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#include +#include +#include +#ifdef _WIN32 +# include +#else +# include +#endif + +#include +#include +#include +#include + +#pragma once + +// Simple udp client sink +// Connects to remote address and send the formatted log. +// Will attempt to reconnect if connection drops. +// If more complicated behaviour is needed (i.e get responses), you can inherit it and override the sink_it_ method. + +namespace spdlog { +namespace sinks { + +struct udp_sink_config +{ + std::string server_host; + uint16_t server_port; + + udp_sink_config(std::string host, uint16_t port) + : server_host{std::move(host)} + , server_port{port} + {} +}; + +template +class udp_sink : public spdlog::sinks::base_sink +{ +public: + // connect to tcp host/port or throw if failed + // host can be hostname or ip address + + explicit udp_sink(udp_sink_config sink_config) + : config_{std::move(sink_config)} + { + + } + + ~udp_sink() override = default; + +protected: + void sink_it_(const spdlog::details::log_msg &msg) override + { + spdlog::memory_buf_t formatted; + spdlog::sinks::base_sink::formatter_->format(msg, formatted); + if (!client_.is_init()) + { + client_.init(config_.server_host, config_.server_port); + } + client_.send(formatted.data(), formatted.size()); + } + + void flush_() override {} + udp_sink_config config_; + details::udp_client client_; +}; + +using udp_sink_mt = udp_sink; +using udp_sink_st = udp_sink; + +} // namespace sinks + +// +// factory functions +// +template +inline std::shared_ptr udp_logger_mt(const std::string &logger_name, sinks::udp_sink_config skin_config) +{ + return Factory::template create(logger_name, skin_config); +} + +} // namespace spdlog \ No newline at end of file From 410e641dffdcedce0324b6ee73b0813bdffb0983 Mon Sep 17 00:00:00 2001 From: Chris Love Date: Thu, 26 Aug 2021 06:01:22 -0700 Subject: [PATCH 02/11] Fix windows include --- include/spdlog/sinks/udp_sink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h index 961d754d..fd57fd73 100644 --- a/include/spdlog/sinks/udp_sink.h +++ b/include/spdlog/sinks/udp_sink.h @@ -7,7 +7,7 @@ #include #include #ifdef _WIN32 -# include +# include #else # include #endif From a15f5137efca7d29b87e5b82cd449525456414a9 Mon Sep 17 00:00:00 2001 From: Chris Love Date: Thu, 26 Aug 2021 06:35:28 -0700 Subject: [PATCH 03/11] Fix udp sink on Windows --- example/example.cpp | 8 ++++---- .../{udp_client_windows.h => udp_client-windows.h} | 11 ++++++++++- include/spdlog/sinks/udp_sink.h | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) rename include/spdlog/details/{udp_client_windows.h => udp_client-windows.h} (85%) diff --git a/example/example.cpp b/example/example.cpp index 7d7f9bf9..c765ecf9 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -200,7 +200,7 @@ void trace_example() // stopwatch example #include "spdlog/stopwatch.h" #include -#include "spdlog/sinks/udp_sink.h" + void stopwatch_example() { spdlog::stopwatch sw; @@ -208,11 +208,11 @@ void stopwatch_example() spdlog::info("Stopwatch: {} seconds", sw); } +// udp sink example +#include "spdlog/sinks/udp_sink.h" void udp_example() { - // using spdlog::details::make_unique; - //auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); - spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); + spdlog::sinks::udp_sink_config cfg("192.168.1.129", 11091); auto my_logger = spdlog::udp_logger_mt("udplog", cfg); my_logger->set_level(spdlog::level::debug); my_logger->info("hello world"); diff --git a/include/spdlog/details/udp_client_windows.h b/include/spdlog/details/udp_client-windows.h similarity index 85% rename from include/spdlog/details/udp_client_windows.h rename to include/spdlog/details/udp_client-windows.h index 82d800a6..4ac37222 100644 --- a/include/spdlog/details/udp_client_windows.h +++ b/include/spdlog/details/udp_client-windows.h @@ -82,6 +82,15 @@ public: addr_.sin_family = AF_INET; addr_.sin_port = htons(port); InetPton(AF_INET, TEXT(host.c_str()), &addr_.sin_addr.s_addr); + + socket_ = socket(PF_INET, SOCK_DGRAM, 0); + if (socket_ == INVALID_SOCKET) + { + int last_error = ::WSAGetLastError(); + WSACleanup(); + throw_winsock_error_("error: Create Socket failed", last_error); + return false; + } return true; } @@ -104,7 +113,7 @@ public: void send(const char *data, size_t n_bytes) { - if ((sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&addr_, sizeof(struct sockaddr))) == -1) + if ((sendto(socket_, data, static_cast(n_bytes), 0, (struct sockaddr *)&addr_, sizeof(struct sockaddr))) == -1) { throw_spdlog_ex("sendto(2) failed", errno); close(); diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h index fd57fd73..961d754d 100644 --- a/include/spdlog/sinks/udp_sink.h +++ b/include/spdlog/sinks/udp_sink.h @@ -7,7 +7,7 @@ #include #include #ifdef _WIN32 -# include +# include #else # include #endif From 649424b8ea3cb3c19dd459c5f26c23a916a111a4 Mon Sep 17 00:00:00 2001 From: Chris Love Date: Thu, 26 Aug 2021 06:36:31 -0700 Subject: [PATCH 04/11] Fix IP address of udp sink example --- example/example.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index c765ecf9..5e7e60de 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -212,7 +212,7 @@ void stopwatch_example() #include "spdlog/sinks/udp_sink.h" void udp_example() { - spdlog::sinks::udp_sink_config cfg("192.168.1.129", 11091); + spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); auto my_logger = spdlog::udp_logger_mt("udplog", cfg); my_logger->set_level(spdlog::level::debug); my_logger->info("hello world"); @@ -231,15 +231,15 @@ void multi_sink_example() spdlog::logger logger("multi_sink", {console_sink, file_sink}); logger.set_level(spdlog::level::debug); - logger.warn("this should appear in both console and file"); - logger.info("this message should not appear in the console, only in the file"); -} + logger.warn("this should // User defined types logging by implementing operator<< struct my_type { int i; - template + templateappear in both console and file"); + logger.info("this message should not appear in the console, only in the file"); +} friend OStream &operator<<(OStream &os, const my_type &c) { return os << "[my_type i=" << c.i << "]"; From 4501f21ae756d25b173f1080c74f6a3bde5ba076 Mon Sep 17 00:00:00 2001 From: Chris Love Date: Thu, 26 Aug 2021 18:50:55 -0700 Subject: [PATCH 05/11] Fix example --- example/example.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index 5e7e60de..8ce5e69c 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -200,7 +200,7 @@ void trace_example() // stopwatch example #include "spdlog/stopwatch.h" #include - +#include "spdlog/sinks/udp_sink.h" void stopwatch_example() { spdlog::stopwatch sw; @@ -208,8 +208,6 @@ void stopwatch_example() spdlog::info("Stopwatch: {} seconds", sw); } -// udp sink example -#include "spdlog/sinks/udp_sink.h" void udp_example() { spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); @@ -231,15 +229,15 @@ void multi_sink_example() spdlog::logger logger("multi_sink", {console_sink, file_sink}); logger.set_level(spdlog::level::debug); - logger.warn("this should + logger.warn("this should appear in both console and file"); + logger.info("this message should not appear in the console, only in the file"); +} // User defined types logging by implementing operator<< struct my_type { int i; - templateappear in both console and file"); - logger.info("this message should not appear in the console, only in the file"); -} + template friend OStream &operator<<(OStream &os, const my_type &c) { return os << "[my_type i=" << c.i << "]"; From 486dc5102ea07b6bbfc1c9eeb29a0d6b904bf1ca Mon Sep 17 00:00:00 2001 From: Chris Love Date: Fri, 3 Sep 2021 10:53:29 -0700 Subject: [PATCH 06/11] Winsock support --- example/example.cpp | 15 +++++++++++---- include/spdlog/details/udp_client-windows.h | 8 +++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index 8ce5e69c..c580f796 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -5,6 +5,7 @@ // spdlog usage example #include +#include void load_levels_example(); void stdout_logger_example(); @@ -19,8 +20,8 @@ void multi_sink_example(); void user_defined_example(); void err_handler_example(); void syslog_example(); -void custom_flags_example(); void udp_example(); +void custom_flags_example(); #include "spdlog/spdlog.h" #include "spdlog/cfg/env.h" // support for loading levels from the environment variable @@ -75,8 +76,8 @@ int main(int, char *[]) err_handler_example(); trace_example(); stopwatch_example(); - custom_flags_example(); udp_example(); + custom_flags_example(); // Flush all *registered* loggers using a worker thread every 3 seconds. // note: registered loggers *must* be thread safe for this to work correctly! @@ -208,13 +209,19 @@ void stopwatch_example() spdlog::info("Stopwatch: {} seconds", sw); } +using namespace std::chrono_literals; void udp_example() { spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); auto my_logger = spdlog::udp_logger_mt("udplog", cfg); my_logger->set_level(spdlog::level::debug); - my_logger->info("hello world"); - my_logger->info("are you ok"); + for (int i = 0; i < 10; i++) { + my_logger->info("hello world {}", i); +#ifndef _WIN32 + // sendto() on winsock will drop packets if sent too quickly + std::this_thread::sleep_for(40ms); +#endif + } } // A logger with multiple sinks (stdout and file) - each with a different format and log level. diff --git a/include/spdlog/details/udp_client-windows.h b/include/spdlog/details/udp_client-windows.h index 4ac37222..0eb8cb40 100644 --- a/include/spdlog/details/udp_client-windows.h +++ b/include/spdlog/details/udp_client-windows.h @@ -79,9 +79,10 @@ public: close(); } - addr_.sin_family = AF_INET; + addr_.sin_family = PF_INET; addr_.sin_port = htons(port); - InetPton(AF_INET, TEXT(host.c_str()), &addr_.sin_addr.s_addr); + addr_.sin_addr.s_addr = INADDR_ANY; + InetPton(PF_INET, TEXT(host.c_str()), &addr_.sin_addr.s_addr); socket_ = socket(PF_INET, SOCK_DGRAM, 0); if (socket_ == INVALID_SOCKET) @@ -113,7 +114,8 @@ public: void send(const char *data, size_t n_bytes) { - if ((sendto(socket_, data, static_cast(n_bytes), 0, (struct sockaddr *)&addr_, sizeof(struct sockaddr))) == -1) + socklen_t tolen = sizeof(struct sockaddr); + if (sendto(socket_, data, static_cast(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1) { throw_spdlog_ex("sendto(2) failed", errno); close(); From 8ee1c167b976d5baac8e9ada1eec45a924a5a42d Mon Sep 17 00:00:00 2001 From: Chris Love Date: Fri, 3 Sep 2021 11:02:12 -0700 Subject: [PATCH 07/11] Don't use std::chrono_literals --- example/example.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index c580f796..5d588e1b 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -209,7 +209,6 @@ void stopwatch_example() spdlog::info("Stopwatch: {} seconds", sw); } -using namespace std::chrono_literals; void udp_example() { spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); @@ -217,9 +216,9 @@ void udp_example() my_logger->set_level(spdlog::level::debug); for (int i = 0; i < 10; i++) { my_logger->info("hello world {}", i); -#ifndef _WIN32 +#ifdef _WIN32 // sendto() on winsock will drop packets if sent too quickly - std::this_thread::sleep_for(40ms); + std::this_thread::sleep_for(std::chrono::milliseconds(40)); #endif } } From 444df2b2874a59c5c4578d9b0ee9ca17d98997b4 Mon Sep 17 00:00:00 2001 From: Chris Love Date: Fri, 3 Sep 2021 16:36:49 -0700 Subject: [PATCH 08/11] Address PR comments --- example/example.cpp | 8 +------- include/spdlog/details/udp_client-windows.h | 4 +++- include/spdlog/sinks/udp_sink.h | 7 +------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index 5d588e1b..7fc44850 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -214,13 +214,7 @@ void udp_example() spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); auto my_logger = spdlog::udp_logger_mt("udplog", cfg); my_logger->set_level(spdlog::level::debug); - for (int i = 0; i < 10; i++) { - my_logger->info("hello world {}", i); -#ifdef _WIN32 - // sendto() on winsock will drop packets if sent too quickly - std::this_thread::sleep_for(std::chrono::milliseconds(40)); -#endif - } + my_logger->info("hello world"); } // A logger with multiple sinks (stdout and file) - each with a different format and log level. diff --git a/include/spdlog/details/udp_client-windows.h b/include/spdlog/details/udp_client-windows.h index 0eb8cb40..b370b127 100644 --- a/include/spdlog/details/udp_client-windows.h +++ b/include/spdlog/details/udp_client-windows.h @@ -3,6 +3,7 @@ #pragma once +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN // tcp client helper #include @@ -125,4 +126,5 @@ public: } // namespace details } // namespace spdlog -#endif \ No newline at end of file +#endif // _WIN32 +#endif // WIN32_LEAN_AND_MEAN \ No newline at end of file diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h index 961d754d..b8706c3d 100644 --- a/include/spdlog/sinks/udp_sink.h +++ b/include/spdlog/sinks/udp_sink.h @@ -17,12 +17,8 @@ #include #include -#pragma once - // Simple udp client sink -// Connects to remote address and send the formatted log. -// Will attempt to reconnect if connection drops. -// If more complicated behaviour is needed (i.e get responses), you can inherit it and override the sink_it_ method. +// Sends formatted log via udp namespace spdlog { namespace sinks { @@ -42,7 +38,6 @@ template class udp_sink : public spdlog::sinks::base_sink { public: - // connect to tcp host/port or throw if failed // host can be hostname or ip address explicit udp_sink(udp_sink_config sink_config) From 2d1217006be6f26de515ebfca2cc491c816a575c Mon Sep 17 00:00:00 2001 From: Chris Love Date: Fri, 3 Sep 2021 16:44:16 -0700 Subject: [PATCH 09/11] Fix #ifdef WINDOWS_LEAN_AND_MEAN --- include/spdlog/details/udp_client-windows.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/udp_client-windows.h b/include/spdlog/details/udp_client-windows.h index b370b127..8ee8527b 100644 --- a/include/spdlog/details/udp_client-windows.h +++ b/include/spdlog/details/udp_client-windows.h @@ -5,7 +5,8 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN -// tcp client helper +#endif // WIN32_LEAN_AND_MEAN +// udp client helper #include #include @@ -127,4 +128,3 @@ public: } // namespace spdlog #endif // _WIN32 -#endif // WIN32_LEAN_AND_MEAN \ No newline at end of file From 497fa60f570834818cd9114d0ca2b173868eaafb Mon Sep 17 00:00:00 2001 From: Chris Love Date: Sat, 4 Sep 2021 13:18:06 -0700 Subject: [PATCH 10/11] Explicitly set SO_SNDBUF size to fix drops on Windows and address other PR feedback --- include/spdlog/details/udp_client-windows.h | 13 +++++++++++-- include/spdlog/details/udp_client.h | 12 ++++++++++-- include/spdlog/sinks/udp_sink.h | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/spdlog/details/udp_client-windows.h b/include/spdlog/details/udp_client-windows.h index 8ee8527b..d56b4135 100644 --- a/include/spdlog/details/udp_client-windows.h +++ b/include/spdlog/details/udp_client-windows.h @@ -26,6 +26,7 @@ namespace spdlog { namespace details { class udp_client { + const int TX_BUFFER_SIZE = 10240; SOCKET socket_ = INVALID_SOCKET; sockaddr_in addr_ = { 0 }; @@ -92,8 +93,16 @@ public: int last_error = ::WSAGetLastError(); WSACleanup(); throw_winsock_error_("error: Create Socket failed", last_error); - return false; } + + int option_value = TX_BUFFER_SIZE; + if (setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, (char*)&option_value, sizeof(option_value)) < 0) + { + int last_error = ::WSAGetLastError(); + close(); + throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error); + } + return true; } @@ -119,8 +128,8 @@ public: socklen_t tolen = sizeof(struct sockaddr); if (sendto(socket_, data, static_cast(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1) { - throw_spdlog_ex("sendto(2) failed", errno); close(); + throw_spdlog_ex("sendto(2) failed", errno); } } }; diff --git a/include/spdlog/details/udp_client.h b/include/spdlog/details/udp_client.h index 13b608c8..6eeb68e3 100644 --- a/include/spdlog/details/udp_client.h +++ b/include/spdlog/details/udp_client.h @@ -21,8 +21,10 @@ namespace spdlog { namespace details { + class udp_client { + const int TX_BUFFER_SIZE = 10240; int socket_ = -1; struct sockaddr_in sockAddr_; public: @@ -33,7 +35,13 @@ public: if (socket_ < 0) { throw_spdlog_ex("error: Create Socket Failed!"); - return false; + } + + int option_value = TX_BUFFER_SIZE; + if (setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, (char*)&option_value, sizeof(option_value)) < 0) + { + close(); + throw_spdlog_ex("error: setsockopt(SO_SNDBUF) Failed!"); } sockAddr_.sin_family = AF_INET; @@ -76,8 +84,8 @@ public: socklen_t tolen = sizeof(struct sockaddr); if (( toslen = sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) == -1) { - throw_spdlog_ex("sendto(2) failed", errno); close(); + throw_spdlog_ex("sendto(2) failed", errno); } } }; diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h index b8706c3d..8071a602 100644 --- a/include/spdlog/sinks/udp_sink.h +++ b/include/spdlog/sinks/udp_sink.h @@ -43,7 +43,7 @@ public: explicit udp_sink(udp_sink_config sink_config) : config_{std::move(sink_config)} { - + client_.init(config_.server_host, config_.server_port); } ~udp_sink() override = default; From 2e66a270817dd0676d14ec26532bddbc3e5a009c Mon Sep 17 00:00:00 2001 From: Chris Love Date: Sat, 4 Sep 2021 19:29:56 -0700 Subject: [PATCH 11/11] Remove is_init() check on each log call --- include/spdlog/details/udp_client-windows.h | 10 ++++------ include/spdlog/details/udp_client.h | 7 +------ include/spdlog/sinks/udp_sink.h | 4 ---- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/include/spdlog/details/udp_client-windows.h b/include/spdlog/details/udp_client-windows.h index d56b4135..9b5d5f21 100644 --- a/include/spdlog/details/udp_client-windows.h +++ b/include/spdlog/details/udp_client-windows.h @@ -77,11 +77,6 @@ public: init_winsock_(); } - if (is_init()) - { - close(); - } - addr_.sin_family = PF_INET; addr_.sin_port = htons(port); addr_.sin_addr.s_addr = INADDR_ANY; @@ -108,7 +103,10 @@ public: void close() { - ::closesocket(socket_); + if (socket_ != -1) + { + ::closesocket(socket_); + } socket_ = INVALID_SOCKET; WSACleanup(); } diff --git a/include/spdlog/details/udp_client.h b/include/spdlog/details/udp_client.h index 6eeb68e3..661282cd 100644 --- a/include/spdlog/details/udp_client.h +++ b/include/spdlog/details/udp_client.h @@ -52,14 +52,9 @@ public: return true; } - bool is_init() const - { - return socket_ != -1; - } - void close() { - if (is_init()) + if (socket_ != -1) { ::close(socket_); socket_ = -1; diff --git a/include/spdlog/sinks/udp_sink.h b/include/spdlog/sinks/udp_sink.h index 8071a602..0b35ce41 100644 --- a/include/spdlog/sinks/udp_sink.h +++ b/include/spdlog/sinks/udp_sink.h @@ -53,10 +53,6 @@ protected: { spdlog::memory_buf_t formatted; spdlog::sinks::base_sink::formatter_->format(msg, formatted); - if (!client_.is_init()) - { - client_.init(config_.server_host, config_.server_port); - } client_.send(formatted.data(), formatted.size()); }