Commit f4db1c51 authored by gabime's avatar gabime

catch potential flush exceptions

parent 560df287
......@@ -179,4 +179,6 @@ using filename_t = std::wstring;
using filename_t = std::string;
#endif
#define SPDLOG_CATCH_AND_HANDLE catch (const std::exception &ex) {_err_handler(ex.what());}\
catch (...) {_err_handler("Unknown exeption in logger");}
} // namespace spdlog
......@@ -30,11 +30,13 @@
#include <utility>
#include <vector>
namespace spdlog {
namespace details {
namespace details {
class async_log_helper
{
class async_log_helper
{
// Async msg to move to/from the queue
// Movable only. should never be copied
enum class async_msg_type
......@@ -95,7 +97,7 @@ class async_log_helper
}
};
public:
public:
using item_type = async_msg;
using q_type = details::mpmc_bounded_queue<item_type>;
......@@ -125,7 +127,7 @@ public:
void set_error_handler(spdlog::log_err_handler err_handler);
private:
private:
std::string _logger_name;
formatter_ptr _formatter;
std::vector<std::shared_ptr<sinks::sink>> _sinks;
......@@ -169,8 +171,8 @@ private:
void handle_flush_interval();
void flush_sinks();
};
} // namespace details
};
} // namespace details
} // namespace spdlog
///////////////////////////////////////////////////////////////////////////////
......@@ -251,14 +253,7 @@ inline void spdlog::details::async_log_helper::worker_loop()
{
active = process_next_msg();
}
catch (const std::exception &ex)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exeption in async logger worker loop.");
}
SPDLOG_CATCH_AND_HANDLE
}
if (_worker_teardown_cb)
{
......@@ -295,9 +290,13 @@ inline bool spdlog::details::async_log_helper::process_next_msg()
for (auto &s : _sinks)
{
if (s->should_log(incoming_log_msg.level))
{
try
{
s->log(incoming_log_msg);
}
SPDLOG_CATCH_AND_HANDLE
}
}
handle_flush_interval();
return true;
......@@ -334,9 +333,14 @@ inline void spdlog::details::async_log_helper::handle_flush_interval()
// flush all sinks if _flush_interval_ms has expired. only called if queue is empty
inline void spdlog::details::async_log_helper::flush_sinks()
{
for (auto &s : _sinks)
{
try
{
s->flush();
}
SPDLOG_CATCH_AND_HANDLE
}
_last_flush = os::now();
}
......@@ -68,15 +68,7 @@ inline void spdlog::logger::log(level::level_enum lvl, const char *fmt, const Ar
#endif
_sink_it(log_msg);
}
catch (const std::exception &ex)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
SPDLOG_CATCH_AND_HANDLE
}
template<typename... Args>
......@@ -92,15 +84,7 @@ inline void spdlog::logger::log(level::level_enum lvl, const char *msg)
log_msg.raw << msg;
_sink_it(log_msg);
}
catch (const std::exception &ex)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
SPDLOG_CATCH_AND_HANDLE
}
template<typename T>
......@@ -116,15 +100,7 @@ inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
log_msg.raw << msg;
_sink_it(log_msg);
}
catch (const std::exception &ex)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
SPDLOG_CATCH_AND_HANDLE
}
template<typename Arg1, typename... Args>
......@@ -331,10 +307,14 @@ inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter)
inline void spdlog::logger::flush()
{
try
{
for (auto &sink : _sinks)
{
sink->flush();
}
}
SPDLOG_CATCH_AND_HANDLE
}
inline void spdlog::logger::_default_err_handler(const std::string &msg)
......
......@@ -7,14 +7,17 @@
class failing_sink : public spdlog::sinks::sink
{
void log(const spdlog::details::log_msg &msg) override
void log(const spdlog::details::log_msg &) override
{
throw std::runtime_error("some error happened during log");
}
void flush() override {}
void flush() override
{
throw std::runtime_error("some error happened during flush");
}
};
using namespace std;
TEST_CASE("default_error_handler", "[errors]]")
{
prepare_logdir();
......@@ -44,7 +47,7 @@ TEST_CASE("custom_error_handler", "[errors]]")
std::string filename = "logs/simple_log.txt";
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
logger->flush_on(spdlog::level::info);
logger->set_error_handler([=](const std::string &msg) { throw custom_ex(); });
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
logger->info("Good message #1");
#if !defined(SPDLOG_FMT_PRINTF)
REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
......@@ -57,12 +60,19 @@ TEST_CASE("custom_error_handler", "[errors]]")
TEST_CASE("default_error_handler2", "[errors]]")
{
auto logger = spdlog::create<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &msg) { throw custom_ex(); });
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
}
TEST_CASE("flush_error_handler", "[errors]]")
{
spdlog::drop_all();
auto logger = spdlog::create<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
REQUIRE_THROWS_AS(logger->flush(), custom_ex);
}
TEST_CASE("async_error_handler", "[errors]]")
{
prepare_logdir();
......@@ -71,7 +81,7 @@ TEST_CASE("async_error_handler", "[errors]]")
std::string filename = "logs/simple_async_log.txt";
{
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
logger->set_error_handler([=](const std::string &msg) {
logger->set_error_handler([=](const std::string &) {
std::ofstream ofs("logs/custom_err.txt");
if (!ofs)
throw std::runtime_error("Failed open logs/custom_err.txt");
......@@ -99,7 +109,7 @@ TEST_CASE("async_error_handler2", "[errors]]")
spdlog::set_async_mode(128);
{
auto logger = spdlog::create<failing_sink>("failed_logger");
logger->set_error_handler([=](const std::string &msg) {
logger->set_error_handler([=](const std::string &) {
std::ofstream ofs("logs/custom_err2.txt");
if (!ofs)
throw std::runtime_error("Failed open logs/custom_err2.txt");
......@@ -108,6 +118,7 @@ TEST_CASE("async_error_handler2", "[errors]]")
logger->info("Hello failure");
spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown
spdlog::set_sync_mode();
logger.reset();
}
REQUIRE(file_contents("logs/custom_err2.txt") == err_msg);
......
......@@ -50,7 +50,7 @@ TEST_CASE("flush_on", "[flush_on]]")
TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
{
prepare_logdir();
std::string basename = "logs/rotating_log";
std::string basename = "logs/rotating_log_A";
auto logger = spdlog::rotating_logger_mt("logger", basename, 1024, 0);
for (int i = 0; i < 10; ++i)
......@@ -70,8 +70,9 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
{
prepare_logdir();
std::string basename = "logs/rotating_log";
auto logger = spdlog::rotating_logger_mt("logger", basename, 1024, 1);
size_t max_size = 10 * 1024;
std::string basename = "logs/rotating_log.txt";
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 1);
for (int i = 0; i < 10; ++i)
logger->info("Test message {}", i);
......@@ -88,9 +89,9 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
}
logger->flush();
REQUIRE(get_filesize(filename) <= 1024);
auto filename1 = basename + ".1";
REQUIRE(get_filesize(filename1) <= 1024);
REQUIRE(get_filesize(filename) <= max_size);
auto filename1 = "logs/rotating_log.1.txt";
REQUIRE(get_filesize(filename1) <= max_size);
}
TEST_CASE("daily_logger", "[daily_logger]]")
......
......@@ -21,7 +21,7 @@ TEST_CASE("basic async test ", "[async]")
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
size_t queue_size = 128;
size_t messages = 256;
auto logger = spdlog::create_async("as", test_sink, 128, spdlog::async_overflow_policy::block_retry);
auto logger = spdlog::create_async("as", test_sink, queue_size, spdlog::async_overflow_policy::block_retry);
for (size_t i = 0; i < messages; i++)
{
logger->info("Hello message #{}", i);
......

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2015
VisualStudioVersion = 14.0
# Visual Studio 15
VisualStudioVersion = 15.0.27428.2037
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcxproj", "{59A07559-5F38-4DD6-A7FA-DB4153690B42}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "spdlog", "spdlog", "{7EFD7EC9-512F-4B35-ADFE-49863B2C04A5}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\async_logger.h = ..\include\spdlog\async_logger.h
..\include\spdlog\common.h = ..\include\spdlog\common.h
..\include\spdlog\formatter.h = ..\include\spdlog\formatter.h
..\include\spdlog\logger.h = ..\include\spdlog\logger.h
..\include\spdlog\spdlog.h = ..\include\spdlog\spdlog.h
..\include\spdlog\tweakme.h = ..\include\spdlog\tweakme.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "contrib", "contrib", "{AAD3C108-4E24-4AA8-BA09-4C9A75A881B3}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\contrib\README.md = ..\include\spdlog\contrib\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sinks", "sinks", "{3FB7E4DF-2397-463E-BDAD-32854AB66DFD}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\contrib\sinks\.gitignore = ..\include\spdlog\contrib\sinks\.gitignore
..\include\spdlog\contrib\sinks\step_file_sink.h = ..\include\spdlog\contrib\sinks\step_file_sink.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "details", "details", "{97DED9BF-821E-4A7A-8D13-ED9A739E1F55}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\details\async_log_helper.h = ..\include\spdlog\details\async_log_helper.h
..\include\spdlog\details\async_logger_impl.h = ..\include\spdlog\details\async_logger_impl.h
..\include\spdlog\details\file_helper.h = ..\include\spdlog\details\file_helper.h
..\include\spdlog\details\log_msg.h = ..\include\spdlog\details\log_msg.h
..\include\spdlog\details\logger_impl.h = ..\include\spdlog\details\logger_impl.h
..\include\spdlog\details\mpmc_blocking_q.h = ..\include\spdlog\details\mpmc_blocking_q.h
..\include\spdlog\details\null_mutex.h = ..\include\spdlog\details\null_mutex.h
..\include\spdlog\details\os.h = ..\include\spdlog\details\os.h
..\include\spdlog\details\pattern_formatter_impl.h = ..\include\spdlog\details\pattern_formatter_impl.h
..\include\spdlog\details\registry.h = ..\include\spdlog\details\registry.h
..\include\spdlog\details\spdlog_impl.h = ..\include\spdlog\details\spdlog_impl.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fmt", "fmt", "{0B649723-CF78-47C0-B1CA-1F173DDBFED4}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\fmt\fmt.h = ..\include\spdlog\fmt\fmt.h
..\include\spdlog\fmt\ostr.h = ..\include\spdlog\fmt\ostr.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bundled", "bundled", "{1FBA69C4-7EAA-4D60-BCF9-3D59D5A88D32}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\fmt\bundled\format.cc = ..\include\spdlog\fmt\bundled\format.cc
..\include\spdlog\fmt\bundled\format.h = ..\include\spdlog\fmt\bundled\format.h
..\include\spdlog\fmt\bundled\LICENSE.rst = ..\include\spdlog\fmt\bundled\LICENSE.rst
..\include\spdlog\fmt\bundled\ostream.cc = ..\include\spdlog\fmt\bundled\ostream.cc
..\include\spdlog\fmt\bundled\ostream.h = ..\include\spdlog\fmt\bundled\ostream.h
..\include\spdlog\fmt\bundled\posix.cc = ..\include\spdlog\fmt\bundled\posix.cc
..\include\spdlog\fmt\bundled\posix.h = ..\include\spdlog\fmt\bundled\posix.h
..\include\spdlog\fmt\bundled\printf.cc = ..\include\spdlog\fmt\bundled\printf.cc
..\include\spdlog\fmt\bundled\printf.h = ..\include\spdlog\fmt\bundled\printf.h
..\include\spdlog\fmt\bundled\time.h = ..\include\spdlog\fmt\bundled\time.h
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sinks", "sinks", "{278CDF3C-6E6D-4FAF-AF79-C1806101B4CB}"
ProjectSection(SolutionItems) = preProject
..\include\spdlog\sinks\android_sink.h = ..\include\spdlog\sinks\android_sink.h
..\include\spdlog\sinks\ansicolor_sink.h = ..\include\spdlog\sinks\ansicolor_sink.h
..\include\spdlog\sinks\base_sink.h = ..\include\spdlog\sinks\base_sink.h
..\include\spdlog\sinks\dist_sink.h = ..\include\spdlog\sinks\dist_sink.h
..\include\spdlog\sinks\file_sinks.h = ..\include\spdlog\sinks\file_sinks.h
..\include\spdlog\sinks\msvc_sink.h = ..\include\spdlog\sinks\msvc_sink.h
..\include\spdlog\sinks\null_sink.h = ..\include\spdlog\sinks\null_sink.h
..\include\spdlog\sinks\ostream_sink.h = ..\include\spdlog\sinks\ostream_sink.h
..\include\spdlog\sinks\sink.h = ..\include\spdlog\sinks\sink.h
..\include\spdlog\sinks\stdout_sinks.h = ..\include\spdlog\sinks\stdout_sinks.h
..\include\spdlog\sinks\syslog_sink.h = ..\include\spdlog\sinks\syslog_sink.h
..\include\spdlog\sinks\wincolor_sink.h = ..\include\spdlog\sinks\wincolor_sink.h
..\include\spdlog\sinks\windebug_sink.h = ..\include\spdlog\sinks\windebug_sink.h
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
......@@ -25,4 +98,15 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AAD3C108-4E24-4AA8-BA09-4C9A75A881B3} = {7EFD7EC9-512F-4B35-ADFE-49863B2C04A5}
{3FB7E4DF-2397-463E-BDAD-32854AB66DFD} = {AAD3C108-4E24-4AA8-BA09-4C9A75A881B3}
{97DED9BF-821E-4A7A-8D13-ED9A739E1F55} = {7EFD7EC9-512F-4B35-ADFE-49863B2C04A5}
{0B649723-CF78-47C0-B1CA-1F173DDBFED4} = {7EFD7EC9-512F-4B35-ADFE-49863B2C04A5}
{1FBA69C4-7EAA-4D60-BCF9-3D59D5A88D32} = {0B649723-CF78-47C0-B1CA-1F173DDBFED4}
{278CDF3C-6E6D-4FAF-AF79-C1806101B4CB} = {7EFD7EC9-512F-4B35-ADFE-49863B2C04A5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {25A6A4D3-9B25-4071-81B4-99DFDD066255}
EndGlobalSection
EndGlobal
......@@ -30,9 +30,6 @@
<ClCompile Include="utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="errors.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test_macros.cpp">
<Filter>Source Files</Filter>
</ClCompile>
......@@ -42,6 +39,9 @@
<ClCompile Include="test_misc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="errors.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test_async.cpp">
<Filter>Source Files</Filter>
</ClCompile>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment