Line data Source code
1 : /*
2 : * Copyright (c) 2006-2021 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * https://snapwebsites.org/project/snaplogger
5 : * contact@m2osw.com
6 : *
7 : * This program is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 2 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License along
18 : * with this program; if not, write to the Free Software Foundation, Inc.,
19 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 : */
21 :
22 : // self
23 : //
24 : #include "main.h"
25 :
26 :
27 : // snaplogger lib
28 : //
29 : #include <snaplogger/buffer_appender.h>
30 : #include <snaplogger/exception.h>
31 : #include <snaplogger/format.h>
32 : #include <snaplogger/logger.h>
33 : #include <snaplogger/map_diagnostic.h>
34 : #include <snaplogger/message.h>
35 : #include <snaplogger/severity.h>
36 : #include <snaplogger/version.h>
37 :
38 :
39 : // C lib
40 : //
41 : #include <unistd.h>
42 :
43 :
44 :
45 4 : CATCH_TEST_CASE("not_a_message", "[message]")
46 : {
47 4 : CATCH_START_SECTION("Call send_message() with wrong ostream")
48 : {
49 1 : CATCH_REQUIRE_THROWS_MATCHES(
50 : snaplogger::send_message(std::cout)
51 : , snaplogger::not_a_message
52 : , Catch::Matchers::ExceptionMessage(
53 : "logger_error: the 'out' parameter to the send_message() function is expected to be a snaplogger::message object."));
54 : }
55 : CATCH_END_SECTION()
56 :
57 4 : CATCH_START_SECTION("Print snaplogger::secure to wrong ostream")
58 : {
59 2 : std::stringstream buffer;
60 1 : std::streambuf * old(std::cout.rdbuf(buffer.rdbuf()));
61 1 : std::cout << snaplogger::secure << std::endl;
62 1 : CATCH_REQUIRE(buffer.str() == "(section:secure)\n");
63 1 : std::cout.rdbuf(old);
64 : }
65 : CATCH_END_SECTION()
66 2 : }
67 :
68 :
69 :
70 4 : CATCH_TEST_CASE("message_capture", "[message]")
71 : {
72 4 : CATCH_START_SECTION("Message Buffering")
73 : {
74 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-logging");
75 :
76 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
77 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
78 :
79 1 : CATCH_REQUIRE(buffer->get_type() == "buffer");
80 :
81 1 : char const * cargv[] =
82 : {
83 : "/usr/bin/daemon",
84 : nullptr
85 : };
86 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
87 1 : char ** argv = const_cast<char **>(cargv);
88 :
89 1 : advgetopt::options_environment environment_options;
90 1 : environment_options.f_project_name = "test-logger";
91 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
92 2 : advgetopt::getopt opts(environment_options);
93 1 : opts.parse_program_name(argv);
94 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
95 :
96 1 : buffer->set_config(opts);
97 :
98 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${severity}: ${message}"));
99 1 : buffer->set_format(f);
100 :
101 1 : l->add_appender(buffer);
102 :
103 1 : SNAP_LOG_ERROR << snaplogger::precise_time << "Logging this error" << SNAP_LOG_SEND;
104 1 : CATCH_REQUIRE(buffer->str() == "error: Logging this error\n");
105 :
106 : // test the other str() function too
107 : //
108 1 : buffer->str("Start: ");
109 :
110 : // show that the "\n" does not get duplicated
111 : //
112 1 : SNAP_LOG_ERROR << "Error with newline\n" << SNAP_LOG_SEND;
113 1 : CATCH_REQUIRE(buffer->str() == "Start: error: Error with newline\n");
114 1 : buffer->clear();
115 :
116 : // show that the "\r\n" gets replaced by "\n"
117 : //
118 1 : SNAP_LOG_ERROR << "Error with CRLF\r\n" << SNAP_LOG_SEND;
119 1 : CATCH_REQUIRE(buffer->str() == "error: Error with CRLF\n");
120 1 : buffer->clear();
121 :
122 : // severity too low, no change to buffer
123 : //
124 1 : SNAP_LOG_DEBUG << "Debug Message " << M_PI << " which does not make it at all...\n" << SNAP_LOG_SEND;
125 1 : CATCH_REQUIRE(buffer->empty());
126 :
127 1 : l->reset();
128 : }
129 : CATCH_END_SECTION()
130 :
131 4 : CATCH_START_SECTION("JSON Buffering")
132 : {
133 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "json-logging");
134 :
135 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
136 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("json-buffer"));
137 :
138 1 : CATCH_REQUIRE(buffer->get_type() == "buffer");
139 :
140 1 : char const * cargv[] =
141 : {
142 : "/usr/bin/daemon",
143 : nullptr
144 : };
145 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
146 1 : char ** argv = const_cast<char **>(cargv);
147 :
148 1 : advgetopt::options_environment environment_options;
149 1 : environment_options.f_project_name = "json-logger";
150 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
151 2 : advgetopt::getopt opts(environment_options);
152 1 : opts.parse_program_name(argv);
153 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
154 :
155 1 : buffer->set_config(opts);
156 :
157 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>(
158 : "{\"version\":1,"
159 2 : "\"message\":\"${message:escape='\\\r\n\t\"'}\"}"));
160 1 : buffer->set_format(f);
161 :
162 1 : l->add_appender(buffer);
163 :
164 3 : SNAP_LOG_ERROR
165 2 : << SNAP_LOG_FIELD(std::string("format"), std::string("json"))
166 : << "A JSON error message (format:${field:name=format})"
167 : << SNAP_LOG_SEND;
168 1 : CATCH_REQUIRE(buffer->str() == "{\"version\":1,\"message\":\"A JSON error message (format:json)\"}\n");
169 1 : buffer->clear();
170 :
171 : // show that the "\n" does not get duplicated
172 : //
173 5 : SNAP_LOG_ERROR
174 1 : << "See what happens with a \"quoted string\" within the message (${fields})\n"
175 2 : << SNAP_LOG_FIELD(std::string("format"), std::string("json"))
176 2 : << SNAP_LOG_FIELD(std::string("language"), std::string("js"))
177 : << SNAP_LOG_SEND;
178 2 : std::string const expected(std::regex_replace(buffer->str(), std::regex("\\\\\"id\\\\\":\\\\\"[0-9]+\\\\\","), ""));
179 1 : CATCH_REQUIRE(expected == "{\"version\":1,\"message\":\"See what happens with a \\\"quoted string\\\" within the message ({\\\"format\\\":\\\"json\\\",\\\"language\\\":\\\"js\\\"})\"}\n");
180 1 : buffer->clear();
181 :
182 1 : l->reset();
183 : }
184 : CATCH_END_SECTION()
185 2 : }
186 :
187 :
188 3 : CATCH_TEST_CASE("message_copy", "[message]")
189 : {
190 2 : CATCH_START_SECTION("Copy Message")
191 : {
192 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-copying");
193 :
194 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
195 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
196 :
197 1 : CATCH_REQUIRE(buffer->get_type() == "buffer");
198 :
199 1 : char const * cargv[] =
200 : {
201 : "/usr/bin/daemon",
202 : nullptr
203 : };
204 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
205 1 : char ** argv = const_cast<char **>(cargv);
206 :
207 1 : advgetopt::options_environment environment_options;
208 1 : environment_options.f_project_name = "test-logger";
209 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
210 2 : advgetopt::getopt opts(environment_options);
211 1 : opts.parse_program_name(argv);
212 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
213 :
214 1 : buffer->set_config(opts);
215 :
216 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
217 1 : buffer->set_format(f);
218 :
219 1 : l->add_appender(buffer);
220 :
221 1 : int const line_number = __LINE__;
222 1 : snaplogger::message::pointer_t msg(std::make_shared<snaplogger::message>
223 2 : (::snaplogger::severity_t::SEVERITY_ERROR, __FILE__, __func__, line_number));
224 :
225 1 : CATCH_REQUIRE(msg->get_filename() == __FILE__);
226 1 : CATCH_REQUIRE(msg->get_function() == __func__);
227 1 : CATCH_REQUIRE(msg->get_line() == line_number);
228 :
229 1 : msg->set_filename("logger.cpp");
230 1 : msg->set_function("magical");
231 1 : msg->set_line(701);
232 :
233 1 : CATCH_REQUIRE(msg->get_filename() == "logger.cpp");
234 1 : CATCH_REQUIRE(msg->get_function() == "magical");
235 1 : CATCH_REQUIRE(msg->get_line() == 701);
236 :
237 1 : *msg << "Logging an error.";
238 :
239 1 : CATCH_REQUIRE(msg->str() == "Logging an error.");
240 :
241 2 : snaplogger::message::pointer_t copy(std::make_shared<snaplogger::message>(*msg, *msg));
242 :
243 1 : CATCH_REQUIRE(msg->str() == "Logging an error.");
244 1 : CATCH_REQUIRE(copy->str() == "Logging an error.");
245 :
246 : // no destructor called, the output is still empty
247 : //
248 1 : CATCH_REQUIRE(buffer->empty());
249 :
250 1 : copy.reset();
251 :
252 : // msg not lost
253 : //
254 1 : CATCH_REQUIRE(msg->str() == "Logging an error.");
255 :
256 : // destructor against copy does not trigger send_message()
257 : //
258 1 : CATCH_REQUIRE(buffer->empty());
259 :
260 1 : snaplogger::send_message(*msg);
261 :
262 : // now we get the message as expected!
263 : //
264 : // (note that internally we can skip receiving the message on the
265 : // original, but not as a client... we may want to have the ability
266 : // to cancel a message, though.)
267 : //
268 1 : CATCH_REQUIRE(buffer->str() == "Logging an error.\n");
269 :
270 1 : msg.reset();
271 :
272 1 : CATCH_REQUIRE(buffer->str() == "Logging an error.\n");
273 :
274 1 : l->reset();
275 : }
276 : CATCH_END_SECTION()
277 1 : }
278 :
279 :
280 4 : CATCH_TEST_CASE("message_severity", "[message][severity]")
281 : {
282 4 : CATCH_START_SECTION("Appender vs Message severity")
283 : {
284 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-severity");
285 :
286 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
287 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
288 :
289 1 : char const * cargv[] =
290 : {
291 : "/usr/bin/daemon",
292 : nullptr
293 : };
294 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
295 1 : char ** argv = const_cast<char **>(cargv);
296 :
297 1 : advgetopt::options_environment environment_options;
298 1 : environment_options.f_project_name = "test-logger";
299 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
300 2 : advgetopt::getopt opts(environment_options);
301 1 : opts.parse_program_name(argv);
302 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
303 :
304 1 : buffer->set_config(opts);
305 :
306 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
307 1 : buffer->set_format(f);
308 :
309 1 : l->add_appender(buffer);
310 :
311 1 : int const min_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MIN));
312 1 : int const max_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MAX));
313 257 : for(int i(min_severity); i <= max_severity; ++i)
314 : {
315 256 : buffer->set_severity(static_cast<snaplogger::severity_t>(i));
316 65792 : for(int j(min_severity); j <= max_severity; ++j)
317 : {
318 131072 : snaplogger::send_message(
319 131072 : ::snaplogger::message(
320 : static_cast<::snaplogger::severity_t>(j)
321 : , __FILE__
322 : , __func__
323 : , __LINE__
324 65536 : ) << "The message itself");
325 :
326 65536 : if(j >= i
327 32896 : && i != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF)
328 32895 : && j != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF))
329 : {
330 32640 : CATCH_REQUIRE(buffer->str() == "The message itself\n");
331 : }
332 : else
333 : {
334 32896 : CATCH_REQUIRE(buffer->empty());
335 : }
336 65536 : buffer->clear();
337 : }
338 : }
339 :
340 1 : l->reset();
341 : }
342 : CATCH_END_SECTION()
343 :
344 4 : CATCH_START_SECTION("Changing message severity (takes about 3.5min)")
345 : {
346 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-copying");
347 :
348 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
349 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
350 :
351 1 : char const * cargv[] =
352 : {
353 : "/usr/bin/daemon",
354 : nullptr
355 : };
356 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
357 1 : char ** argv = const_cast<char **>(cargv);
358 :
359 1 : advgetopt::options_environment environment_options;
360 1 : environment_options.f_project_name = "test-logger";
361 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
362 2 : advgetopt::getopt opts(environment_options);
363 1 : opts.parse_program_name(argv);
364 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
365 :
366 1 : buffer->set_config(opts);
367 :
368 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
369 1 : buffer->set_format(f);
370 :
371 1 : l->add_appender(buffer);
372 :
373 1 : int const min_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MIN));
374 1 : int const max_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MAX));
375 30 : for(int i(min_severity); i <= max_severity; i += 1 + (rand() & 15))
376 : {
377 29 : buffer->set_severity(static_cast<snaplogger::severity_t>(i));
378 903 : for(int j(min_severity); j <= max_severity; j += 1 + (rand() & 15))
379 : {
380 27861 : for(int k(min_severity); k <= max_severity; k += 1 + (rand() & 15))
381 : {
382 26987 : ::snaplogger::message::pointer_t msg(std::make_shared<::snaplogger::message>(
383 53974 : static_cast<::snaplogger::severity_t>(j)
384 : , __FILE__
385 : , __func__
386 : , __LINE__
387 107948 : ));
388 26987 : *msg << "Start of message";
389 26987 : msg->set_severity(static_cast<::snaplogger::severity_t>(k));
390 26987 : *msg << " -- end of message";
391 26987 : snaplogger::send_message(*msg);
392 : //std::cerr << "checking with " << i << ", " << j << ", " << k << "\n";
393 :
394 26987 : if(j >= i
395 13878 : && k >= i
396 9348 : && i != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF)
397 9348 : && j != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF))
398 : //&& k != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF))
399 : {
400 9218 : if(j >= i)
401 : {
402 9218 : CATCH_REQUIRE(buffer->str() == "Start of message -- end of message\n");
403 : }
404 : else
405 : {
406 0 : CATCH_REQUIRE(buffer->str() == "Start of message\n");
407 9218 : }
408 : }
409 : else
410 : {
411 17769 : CATCH_REQUIRE(buffer->empty());
412 : }
413 26987 : buffer->clear();
414 : }
415 : }
416 : }
417 :
418 1 : l->reset();
419 : }
420 : CATCH_END_SECTION()
421 2 : }
422 :
423 :
424 6 : CATCH_TEST_CASE("message_format", "[message][format]")
425 : {
426 8 : CATCH_START_SECTION("Message is Recursive")
427 : {
428 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "basic-format");
429 :
430 : // these two are not called in this test
431 : //
432 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROJECT_NAME, "test-logger");
433 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_VERSION, "5.32.1024");
434 :
435 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
436 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
437 :
438 1 : char const * cargv[] =
439 : {
440 : "/usr/bin/daemon",
441 : nullptr
442 : };
443 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
444 1 : char ** argv = const_cast<char **>(cargv);
445 :
446 1 : advgetopt::options_environment environment_options;
447 1 : environment_options.f_project_name = "test-logger";
448 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
449 1 : environment_options.f_version = "5.32.1024";
450 2 : advgetopt::getopt opts(environment_options);
451 1 : opts.parse_program_name(argv);
452 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
453 :
454 1 : buffer->set_config(opts);
455 :
456 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${project_name} ${message} v${version}"));
457 1 : buffer->set_format(f);
458 :
459 1 : l->add_appender(buffer);
460 :
461 2 : SNAP_LOG_WARNING
462 1 : << "Message Project Name = ${project_name} and Version = ${version} -- uses \"recursive\""
463 : << SNAP_LOG_SEND;
464 :
465 1 : CATCH_REQUIRE(buffer->str() ==
466 : "test-logger Message Project Name = test-logger and"
467 : " Version = 5.32.1024 -- uses \"recursive\" v5.32.1024"
468 : "\n");
469 :
470 1 : l->reset();
471 : }
472 : CATCH_END_SECTION()
473 :
474 8 : CATCH_START_SECTION("${message} itself is not recursive")
475 : {
476 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "prevent-infinite-loop");
477 :
478 : // these two are not called in this test
479 : //
480 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROJECT_NAME, "test-logger");
481 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_VERSION, "5.32.1024");
482 :
483 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
484 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
485 :
486 1 : char const * cargv[] =
487 : {
488 : "/usr/bin/daemon",
489 : nullptr
490 : };
491 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
492 1 : char ** argv = const_cast<char **>(cargv);
493 :
494 1 : advgetopt::options_environment environment_options;
495 1 : environment_options.f_project_name = "test-logger";
496 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
497 1 : environment_options.f_version = "5.32.1024";
498 2 : advgetopt::getopt opts(environment_options);
499 1 : opts.parse_program_name(argv);
500 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
501 :
502 1 : buffer->set_config(opts);
503 :
504 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${project_name} ${message} v${version}"));
505 1 : buffer->set_format(f);
506 :
507 1 : l->add_appender(buffer);
508 :
509 2 : SNAP_LOG_WARNING
510 1 : << "Message ${message} says: Project Name = ${project_name} and Version = ${version} -- uses \"recursive\""
511 : << SNAP_LOG_SEND;
512 :
513 1 : CATCH_REQUIRE(buffer->str() ==
514 : "test-logger Message says: Project Name = test-logger and"
515 : " Version = 5.32.1024 -- uses \"recursive\" v5.32.1024"
516 : "\n");
517 :
518 1 : buffer->clear();
519 :
520 1 : snaplogger::unset_diagnostic(snaplogger::DIAG_KEY_VERSION);
521 :
522 2 : SNAP_LOG_WARNING
523 1 : << "Removed the version: ${message} says: Project Name = ${project_name} and Version = ${version} -- uses \"recursive\""
524 : << SNAP_LOG_SEND;
525 :
526 1 : CATCH_REQUIRE(buffer->str() ==
527 : "test-logger Removed the version: says: Project Name = test-logger and"
528 : " Version = -- uses \"recursive\" v"
529 : "\n");
530 :
531 1 : l->reset();
532 : }
533 : CATCH_END_SECTION()
534 :
535 8 : CATCH_START_SECTION("${pid} uses the get_environment() function")
536 : {
537 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "get-environment");
538 :
539 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
540 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
541 :
542 1 : char const * cargv[] =
543 : {
544 : "/usr/bin/daemon",
545 : nullptr
546 : };
547 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
548 1 : char ** argv = const_cast<char **>(cargv);
549 :
550 1 : advgetopt::options_environment environment_options;
551 1 : environment_options.f_project_name = "test-logger";
552 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
553 2 : advgetopt::getopt opts(environment_options);
554 1 : opts.parse_program_name(argv);
555 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
556 :
557 1 : buffer->set_config(opts);
558 :
559 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
560 1 : buffer->set_format(f);
561 :
562 1 : l->add_appender(buffer);
563 :
564 2 : SNAP_LOG_WARNING
565 1 : << "Test PID = ${pid} == ${pid:running}"
566 : << SNAP_LOG_SEND;
567 :
568 1 : CATCH_REQUIRE(buffer->str() ==
569 : "Test PID = " + std::to_string(getpid())
570 : + " == " + std::to_string(getpid())
571 : + "\n");
572 :
573 1 : l->reset();
574 : }
575 : CATCH_END_SECTION()
576 :
577 8 : CATCH_START_SECTION("Verify year")
578 : {
579 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "get-environment");
580 :
581 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
582 1 : CATCH_REQUIRE(l->get_appender("test-buffer") == nullptr);
583 :
584 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
585 :
586 1 : char const * cargv[] =
587 : {
588 : "/usr/bin/daemon",
589 : nullptr
590 : };
591 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
592 1 : char ** argv = const_cast<char **>(cargv);
593 :
594 1 : advgetopt::options_environment environment_options;
595 1 : environment_options.f_project_name = "test-logger";
596 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
597 2 : advgetopt::getopt opts(environment_options);
598 1 : opts.parse_program_name(argv);
599 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
600 :
601 1 : buffer->set_config(opts);
602 :
603 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
604 1 : buffer->set_format(f);
605 :
606 1 : l->add_appender(buffer);
607 :
608 1 : CATCH_REQUIRE(l->get_appender("test-buffer") == buffer);
609 :
610 : // we create a message so we can check the timestamp in our test
611 : //
612 1 : snaplogger::message::pointer_t msg(std::make_shared<snaplogger::message>
613 2 : (::snaplogger::severity_t::SEVERITY_ERROR, __FILE__, __func__, __LINE__));
614 1 : *msg << "Created message on YYYY = ${date:year}, MM = ${date:month}, DD = ${date:day}";
615 :
616 1 : timespec const stamp(msg->get_timestamp());
617 :
618 1 : snaplogger::send_message(*msg);
619 :
620 1 : tm t;
621 1 : gmtime_r(&stamp.tv_sec, &t);
622 1 : char year[16];
623 1 : char month[16];
624 1 : char day[16];
625 1 : strftime(year, 16, "%Y", &t);
626 1 : strftime(month, 16, "%m", &t);
627 1 : strftime(day, 16, "%d", &t);
628 :
629 1 : CATCH_REQUIRE(buffer->str() ==
630 : std::string("Created message on YYYY = ")
631 : + year
632 : + ", MM = "
633 : + std::to_string(std::atoi(month)) // remove the leading '0' if necessary
634 : + ", DD = "
635 : + std::to_string(std::atoi(day)) // remove the leading '0' if necessary
636 : + "\n");
637 :
638 1 : l->reset();
639 : }
640 : CATCH_END_SECTION()
641 4 : }
642 :
643 :
644 3 : CATCH_TEST_CASE("message_component_filter", "[message][component]")
645 : {
646 2 : CATCH_START_SECTION("Filter Message with Component")
647 : {
648 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "component-filter");
649 :
650 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
651 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
652 :
653 1 : char const * cargv[] =
654 : {
655 : "/usr/bin/daemon",
656 : nullptr
657 : };
658 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
659 1 : char ** argv = const_cast<char **>(cargv);
660 :
661 1 : advgetopt::options_environment environment_options;
662 1 : environment_options.f_project_name = "test-logger";
663 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
664 2 : advgetopt::getopt opts(environment_options);
665 1 : opts.parse_program_name(argv);
666 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
667 :
668 1 : buffer->set_config(opts);
669 :
670 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message} (${severity:format=number})"));
671 1 : buffer->set_format(f);
672 :
673 1 : l->add_appender(buffer);
674 :
675 2 : SNAP_LOG_WARNING
676 1 : << snaplogger::secure // mark as a secure message
677 : << "This message is secure but not the buffer"
678 : << SNAP_LOG_SEND;
679 :
680 1 : CATCH_REQUIRE(buffer->empty());
681 :
682 2 : SNAP_LOG_WARNING
683 1 : << "Test number: "
684 : << 2
685 1 : << " with buffer still unsecure..."
686 1 : << SNAP_LOG_SEND_SECURELY; // mark at the end
687 :
688 1 : CATCH_REQUIRE(buffer->empty());
689 :
690 : // mark the buffer as a secure buffer now
691 : //
692 1 : buffer->add_component(snaplogger::g_secure_component);
693 :
694 2 : SNAP_LOG_WARNING
695 1 : << snaplogger::secure // mark as a secure message
696 : << "This message is secure and so is the buffer"
697 : << SNAP_LOG_SEND;
698 :
699 : // TODO: get the WARNING severity level dynamically
700 1 : CATCH_REQUIRE(buffer->str() == "This message is secure and so is the buffer (100)\n");
701 :
702 1 : buffer->clear();
703 :
704 2 : SNAP_LOG_WARNING
705 1 : << "Test number: "
706 : << 4
707 1 : << " with secure buffer...\r\n"
708 1 : << SNAP_LOG_SEND_SECURELY; // mark at the end
709 :
710 : // TODO: get the WARNING severity level dynamically
711 1 : CATCH_REQUIRE(buffer->str() == "Test number: 4 with secure buffer... (100)\n");
712 :
713 1 : l->reset();
714 : }
715 : CATCH_END_SECTION()
716 7 : }
717 :
718 :
719 :
720 : // vim: ts=4 sw=4 et
|