1 | /* |
2 | * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE |
3 | */ |
4 | #include "includes.h" |
5 | |
6 | #include <iostream> |
7 | |
8 | #define SIMPLE_LOG "test_logs/simple_log.txt" |
9 | #define SIMPLE_ASYNC_LOG "test_logs/simple_async_log.txt" |
10 | |
11 | class failing_sink : public spdlog::sinks::base_sink<std::mutex> |
12 | { |
13 | protected: |
14 | void sink_it_(const spdlog::details::log_msg &) final |
15 | { |
16 | throw std::runtime_error("some error happened during log" ); |
17 | } |
18 | |
19 | void flush_() final |
20 | { |
21 | throw std::runtime_error("some error happened during flush" ); |
22 | } |
23 | }; |
24 | |
25 | TEST_CASE("default_error_handler" , "[errors]]" ) |
26 | { |
27 | prepare_logdir(); |
28 | spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); |
29 | |
30 | auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("test-error" , filename, true); |
31 | logger->set_pattern("%v" ); |
32 | logger->info(SPDLOG_FMT_RUNTIME("Test message {} {}" ), 1); |
33 | logger->info("Test message {}" , 2); |
34 | logger->flush(); |
35 | |
36 | using spdlog::details::os::default_eol; |
37 | REQUIRE(file_contents(SIMPLE_LOG) == spdlog::fmt_lib::format("Test message 2{}" , default_eol)); |
38 | REQUIRE(count_lines(SIMPLE_LOG) == 1); |
39 | } |
40 | |
41 | struct custom_ex |
42 | {}; |
43 | TEST_CASE("custom_error_handler" , "[errors]]" ) |
44 | { |
45 | prepare_logdir(); |
46 | spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); |
47 | auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger" , filename, true); |
48 | logger->flush_on(spdlog::level::info); |
49 | logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); |
50 | logger->info("Good message #1" ); |
51 | |
52 | REQUIRE_THROWS_AS(logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}" ), "xxx" ), custom_ex); |
53 | logger->info("Good message #2" ); |
54 | require_message_count(SIMPLE_LOG, 2); |
55 | } |
56 | |
57 | TEST_CASE("default_error_handler2" , "[errors]]" ) |
58 | { |
59 | spdlog::drop_all(); |
60 | auto logger = spdlog::create<failing_sink>("failed_logger" ); |
61 | logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); |
62 | REQUIRE_THROWS_AS(logger->info("Some message" ), custom_ex); |
63 | } |
64 | |
65 | TEST_CASE("flush_error_handler" , "[errors]]" ) |
66 | { |
67 | spdlog::drop_all(); |
68 | auto logger = spdlog::create<failing_sink>("failed_logger" ); |
69 | logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); |
70 | REQUIRE_THROWS_AS(logger->flush(), custom_ex); |
71 | } |
72 | |
73 | TEST_CASE("async_error_handler" , "[errors]]" ) |
74 | { |
75 | prepare_logdir(); |
76 | std::string err_msg("log failed with some msg" ); |
77 | |
78 | spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_ASYNC_LOG); |
79 | { |
80 | spdlog::init_thread_pool(128, 1); |
81 | auto logger = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger" , filename, true); |
82 | logger->set_error_handler([=](const std::string &) { |
83 | std::ofstream ofs("test_logs/custom_err.txt" ); |
84 | if (!ofs) |
85 | { |
86 | throw std::runtime_error("Failed open test_logs/custom_err.txt" ); |
87 | } |
88 | ofs << err_msg; |
89 | }); |
90 | logger->info("Good message #1" ); |
91 | logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}" ), "xxx" ); |
92 | logger->info("Good message #2" ); |
93 | spdlog::drop("logger" ); // force logger to drain the queue and shutdown |
94 | } |
95 | spdlog::init_thread_pool(128, 1); |
96 | require_message_count(SIMPLE_ASYNC_LOG, 2); |
97 | REQUIRE(file_contents("test_logs/custom_err.txt" ) == err_msg); |
98 | } |
99 | |
100 | // Make sure async error handler is executed |
101 | TEST_CASE("async_error_handler2" , "[errors]]" ) |
102 | { |
103 | prepare_logdir(); |
104 | std::string err_msg("This is async handler error message" ); |
105 | { |
106 | spdlog::details::os::create_dir(SPDLOG_FILENAME_T("test_logs" )); |
107 | spdlog::init_thread_pool(128, 1); |
108 | auto logger = spdlog::create_async<failing_sink>("failed_logger" ); |
109 | logger->set_error_handler([=](const std::string &) { |
110 | std::ofstream ofs("test_logs/custom_err2.txt" ); |
111 | if (!ofs) |
112 | throw std::runtime_error("Failed open test_logs/custom_err2.txt" ); |
113 | ofs << err_msg; |
114 | }); |
115 | logger->info("Hello failure" ); |
116 | spdlog::drop("failed_logger" ); // force logger to drain the queue and shutdown |
117 | } |
118 | |
119 | spdlog::init_thread_pool(128, 1); |
120 | REQUIRE(file_contents("test_logs/custom_err2.txt" ) == err_msg); |
121 | } |
122 | |