1 | #if _WIN32 |
2 | |
3 | # include "includes.h" |
4 | # include "test_sink.h" |
5 | |
6 | # include "spdlog/sinks/win_eventlog_sink.h" |
7 | |
8 | static const LPCSTR TEST_SOURCE = "spdlog_test" ; |
9 | |
10 | static void test_single_print(std::function<void(std::string const &)> do_log, std::string const &expected_contents, WORD expected_ev_type) |
11 | { |
12 | using namespace std::chrono; |
13 | do_log(expected_contents); |
14 | const auto expected_time_generated = duration_cast<seconds>(system_clock::now().time_since_epoch()).count(); |
15 | |
16 | struct handle_t |
17 | { |
18 | HANDLE handle_; |
19 | |
20 | ~handle_t() |
21 | { |
22 | if (handle_) |
23 | { |
24 | REQUIRE(CloseEventLog(handle_)); |
25 | } |
26 | } |
27 | } event_log{::OpenEventLogA(nullptr, TEST_SOURCE)}; |
28 | |
29 | REQUIRE(event_log.handle_); |
30 | |
31 | DWORD read_bytes{}, size_needed{}; |
32 | auto ok = ::ReadEventLogA( |
33 | event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, &read_bytes, 0, &read_bytes, &size_needed); |
34 | REQUIRE(!ok); |
35 | REQUIRE(::GetLastError() == ERROR_INSUFFICIENT_BUFFER); |
36 | |
37 | std::vector<char> record_buffer(size_needed); |
38 | PEVENTLOGRECORD record = (PEVENTLOGRECORD)record_buffer.data(); |
39 | |
40 | ok = ::ReadEventLogA( |
41 | event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, record, size_needed, &read_bytes, &size_needed); |
42 | REQUIRE(ok); |
43 | |
44 | REQUIRE(record->NumStrings == 1); |
45 | REQUIRE(record->EventType == expected_ev_type); |
46 | REQUIRE((expected_time_generated - record->TimeGenerated) <= 3u); |
47 | |
48 | std::string message_in_log(((char *)record + record->StringOffset)); |
49 | REQUIRE(message_in_log == expected_contents + spdlog::details::os::default_eol); |
50 | } |
51 | |
52 | TEST_CASE("eventlog" , "[eventlog]" ) |
53 | { |
54 | using namespace spdlog; |
55 | |
56 | auto test_sink = std::make_shared<sinks::win_eventlog_sink_mt>(TEST_SOURCE); |
57 | |
58 | spdlog::logger test_logger("eventlog" , test_sink); |
59 | test_logger.set_level(level::trace); |
60 | |
61 | test_sink->set_pattern("%v" ); |
62 | |
63 | test_single_print([&test_logger](std::string const &msg) { test_logger.trace(msg); }, "my trace message" , EVENTLOG_SUCCESS); |
64 | test_single_print([&test_logger](std::string const &msg) { test_logger.debug(msg); }, "my debug message" , EVENTLOG_SUCCESS); |
65 | test_single_print([&test_logger](std::string const &msg) { test_logger.info(msg); }, "my info message" , EVENTLOG_INFORMATION_TYPE); |
66 | test_single_print([&test_logger](std::string const &msg) { test_logger.warn(msg); }, "my warn message" , EVENTLOG_WARNING_TYPE); |
67 | test_single_print([&test_logger](std::string const &msg) { test_logger.error(msg); }, "my error message" , EVENTLOG_ERROR_TYPE); |
68 | test_single_print([&test_logger](std::string const &msg) { test_logger.critical(msg); }, "my critical message" , EVENTLOG_ERROR_TYPE); |
69 | } |
70 | |
71 | #endif //_WIN32 |
72 | |