Commit | Line | Data |
---|---|---|
970ed795 | 1 | /////////////////////////////////////////////////////////////////////////////// |
3abe9331 | 2 | // Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
3 | // All rights reserved. This program and the accompanying materials |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef LOGGER_HH | |
9 | #define LOGGER_HH | |
10 | ||
11 | #include <stdio.h> | |
12 | #include <stdlib.h> | |
13 | #include <stdarg.h> | |
14 | #include <sys/time.h> | |
15 | ||
16 | #include "Types.h" | |
17 | ||
18 | struct log_mask_info; | |
19 | struct Logging_Bits; | |
20 | class LoggerPlugin; | |
21 | class LoggerPluginManager; | |
22 | class CHARSTRING; | |
23 | struct logging_setting_t; | |
24 | ||
25 | /** @brief Logger class | |
26 | ||
27 | Acts as a namespace. No instance data or methods. | |
28 | ||
29 | */ | |
30 | class TTCN_Logger | |
31 | { | |
32 | friend class LoggerPlugin; | |
33 | friend class LoggerPluginManager; | |
34 | public: | |
35 | static LoggerPluginManager *plugins_; | |
36 | // TODO: This should be plug-in specific, but the configuration file parsers | |
37 | // are using this type... | |
38 | enum disk_full_action_type_t { DISKFULL_ERROR, DISKFULL_STOP, | |
39 | DISKFULL_RETRY, DISKFULL_DELETE }; | |
40 | struct disk_full_action_t { | |
41 | disk_full_action_type_t type; | |
42 | size_t retry_interval; | |
43 | }; | |
44 | enum timestamp_format_t { TIMESTAMP_TIME, TIMESTAMP_DATETIME, | |
45 | TIMESTAMP_SECONDS }; | |
46 | enum source_info_format_t { SINFO_NONE, SINFO_SINGLE, SINFO_STACK }; | |
47 | enum log_event_types_t { LOGEVENTTYPES_NO, LOGEVENTTYPES_YES, | |
48 | LOGEVENTTYPES_SUBCATEGORIES }; | |
49 | ||
50 | enum emergency_logging_behaviour_t { BUFFER_ALL, BUFFER_MASKED }; | |
51 | ||
52 | enum matching_verbosity_t { VERBOSITY_COMPACT, VERBOSITY_FULL }; | |
53 | enum extcommand_t { EXTCOMMAND_START, EXTCOMMAND_SUCCESS }; | |
54 | ||
55 | /** Values and templates can be logged in the following formats */ | |
56 | enum data_log_format_t { LF_LEGACY, LF_TTCN }; | |
57 | ||
58 | /** @brief Titan logging severities | |
59 | ||
60 | @note The values are not bit masks. Expressions like | |
61 | @code LOG_ALL | TTCN_DEBUG @endcode will not work correctly. | |
62 | ||
63 | @note This enum must start at 0 and have no gaps until | |
64 | NUMBER_OF_LOGSEVERITIES. | |
65 | */ | |
66 | enum Severity | |
67 | { | |
68 | NOTHING_TO_LOG = 0, // for compatibility | |
69 | ||
70 | ACTION_UNQUALIFIED, | |
71 | ||
72 | DEFAULTOP_ACTIVATE, | |
73 | DEFAULTOP_DEACTIVATE, | |
74 | DEFAULTOP_EXIT, | |
75 | DEFAULTOP_UNQUALIFIED, //5 | |
76 | ||
77 | ERROR_UNQUALIFIED, | |
78 | ||
79 | EXECUTOR_RUNTIME, | |
80 | EXECUTOR_CONFIGDATA, | |
81 | EXECUTOR_EXTCOMMAND, | |
82 | EXECUTOR_COMPONENT, //10 | |
83 | EXECUTOR_LOGOPTIONS, | |
84 | EXECUTOR_UNQUALIFIED, | |
85 | ||
86 | FUNCTION_RND, | |
87 | FUNCTION_UNQUALIFIED, | |
88 | ||
89 | PARALLEL_PTC, //15 | |
90 | PARALLEL_PORTCONN, | |
91 | PARALLEL_PORTMAP, | |
92 | PARALLEL_UNQUALIFIED, | |
93 | ||
94 | TESTCASE_START, | |
95 | TESTCASE_FINISH, //20 | |
96 | TESTCASE_UNQUALIFIED, | |
97 | ||
98 | PORTEVENT_PQUEUE, | |
99 | PORTEVENT_MQUEUE, | |
100 | PORTEVENT_STATE, | |
101 | PORTEVENT_PMIN, //25 | |
102 | PORTEVENT_PMOUT, | |
103 | PORTEVENT_PCIN, | |
104 | PORTEVENT_PCOUT, | |
105 | PORTEVENT_MMRECV, | |
106 | PORTEVENT_MMSEND, //30 | |
107 | PORTEVENT_MCRECV, | |
108 | PORTEVENT_MCSEND, | |
109 | PORTEVENT_DUALRECV, | |
110 | PORTEVENT_DUALSEND, | |
111 | PORTEVENT_UNQUALIFIED, //35 | |
112 | ||
113 | STATISTICS_VERDICT, | |
114 | STATISTICS_UNQUALIFIED, | |
115 | ||
116 | TIMEROP_READ, | |
117 | TIMEROP_START, | |
118 | TIMEROP_GUARD, //40 | |
119 | TIMEROP_STOP, | |
120 | TIMEROP_TIMEOUT, | |
121 | TIMEROP_UNQUALIFIED, | |
122 | ||
123 | USER_UNQUALIFIED, | |
124 | ||
125 | VERDICTOP_GETVERDICT, //45 | |
126 | VERDICTOP_SETVERDICT, | |
127 | VERDICTOP_FINAL, | |
128 | VERDICTOP_UNQUALIFIED, | |
129 | ||
130 | WARNING_UNQUALIFIED, | |
131 | ||
132 | // MATCHING and DEBUG should be at the end (not included in LOG_ALL) | |
133 | MATCHING_DONE, //50 | |
134 | MATCHING_TIMEOUT, | |
135 | MATCHING_PCSUCCESS, | |
136 | MATCHING_PCUNSUCC, | |
137 | MATCHING_PMSUCCESS, | |
138 | MATCHING_PMUNSUCC, //55 | |
139 | MATCHING_MCSUCCESS, | |
140 | MATCHING_MCUNSUCC, | |
141 | MATCHING_MMSUCCESS, | |
142 | MATCHING_MMUNSUCC, | |
143 | MATCHING_PROBLEM, //60 | |
144 | MATCHING_UNQUALIFIED, | |
145 | ||
146 | DEBUG_ENCDEC, | |
147 | DEBUG_TESTPORT, | |
3f84031e | 148 | DEBUG_USER, |
149 | DEBUG_FRAMEWORK, | |
150 | DEBUG_UNQUALIFIED, //66 | |
970ed795 EL |
151 | |
152 | NUMBER_OF_LOGSEVERITIES, // must follow the last individual severity | |
153 | LOG_ALL_IMPORTANT | |
154 | }; | |
155 | /// Number of main severities (plus one, because it includes LOG_NOTHING). | |
156 | static const size_t number_of_categories = 16; | |
157 | /// Main severity names. | |
158 | static const char* severity_category_names[number_of_categories]; | |
159 | /// Sub-category suffixes. | |
160 | static const char* severity_subcategory_names[NUMBER_OF_LOGSEVERITIES]; | |
161 | static const TTCN_Logger::Severity sev_categories[number_of_categories]; | |
162 | ||
163 | static const unsigned int major_version = 2; | |
164 | static const unsigned int minor_version = 2; | |
165 | ||
166 | // buffer used by the log match algorithms to buffer the output | |
167 | static char* logmatch_buffer; | |
168 | // length of the logmatch buffer | |
169 | static size_t logmatch_buffer_len; | |
170 | // the size of the log match buffer (memory allocated for it) | |
171 | static size_t logmatch_buffer_size; | |
172 | // true if the logmatch buffer was already printed in the actual log event. | |
173 | static boolean logmatch_printed; | |
174 | ||
175 | // length of the emergencylogging buffer | |
176 | static size_t emergency_logging; | |
177 | static void set_emergency_logging(size_t size); | |
178 | static size_t get_emergency_logging(); | |
179 | ||
180 | static emergency_logging_behaviour_t emergency_logging_behaviour; | |
181 | static void set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour); | |
182 | static emergency_logging_behaviour_t get_emergency_logging_behaviour(); | |
183 | ||
184 | /** @brief returns the actual length of the logmatch buffer | |
185 | This way it can be stored for later, when the buffer needs to be reverted. | |
186 | @return the length | |
187 | */ | |
188 | static size_t get_logmatch_buffer_len(); | |
189 | ||
190 | /** @brief sets the length of the logmatch buffer | |
191 | Is used to effectively revert the buffer to a previous state. | |
192 | @param new_size the new length to be set. | |
193 | */ | |
194 | static void set_logmatch_buffer_len(size_t new_size); | |
195 | ||
196 | /** @brief prints the contents of the logmatch buffer to the current event | |
197 | Writes contents of the logmatch buffer into the actual event, prefixed with | |
198 | a ',' if needed. | |
199 | */ | |
200 | static void print_logmatch_buffer(); | |
201 | ||
202 | /** @brief Format a string into the current logmatch buffer. | |
203 | @param fmt_str printf-style format string | |
204 | @callgraph | |
205 | */ | |
206 | static void log_logmatch_info(const char *fmt_str, ...) | |
207 | __attribute__ ((__format__ (__printf__, 1, 2))); | |
208 | ||
209 | struct log_mask_struct; // Forward declaration. | |
210 | private: | |
211 | static log_mask_struct console_log_mask; | |
212 | static log_mask_struct file_log_mask; | |
213 | static log_mask_struct emergency_log_mask; | |
214 | ||
215 | ||
216 | static matching_verbosity_t matching_verbosity; | |
217 | ||
218 | static timestamp_format_t timestamp_format; | |
219 | ||
220 | static source_info_format_t source_info_format; | |
221 | ||
222 | static log_event_types_t log_event_types; | |
223 | ||
224 | static struct timeval start_time; | |
225 | ||
226 | static char *executable_name; | |
227 | ||
228 | static boolean log_entity_name; | |
229 | ||
230 | static data_log_format_t data_log_format; | |
231 | ||
232 | /// Always return the single instance of the LoggerPluginManager. | |
233 | static LoggerPluginManager *get_logger_plugin_manager(); | |
234 | /// Returns the actual global logger options. The returned string must be | |
235 | /// freed by the caller. | |
236 | static char *get_logger_settings_str(); | |
237 | ||
238 | public: | |
239 | /** @brief Initialize the logger. | |
240 | ||
241 | @pre initialize_logger has not been called previously | |
242 | */ | |
243 | static void initialize_logger(); | |
244 | ||
245 | /// Frees any resources held by the logger. | |
246 | static void terminate_logger(); | |
247 | ||
248 | static bool is_logger_up(); | |
249 | ||
250 | /** @brief Initializes the logger configuration. | |
251 | ||
252 | \li sets the logfilename template | |
253 | \li sets \c file_mask to LOG_ALL | |
254 | \li sets \c console_mask to TTCN_ERROR | TTCN_WARNING | TTCN_ACTION | TTCN_TESTCASE | TTCN_STATISTICS | |
255 | \li sets \c timestamp_format = TIMESTAMP_TIME; | |
256 | \li sets \c source_info_format = SINFO_NONE; | |
257 | \li sets \c log_event_types = LOGEVENTTYPES_NO; | |
258 | \li sets \c append_file = FALSE; | |
259 | \li sets \c log_entity_name = FALSE; | |
260 | ||
261 | @pre initialize_logger() has been called. | |
262 | ||
263 | */ | |
264 | static void reset_configuration(); | |
265 | ||
266 | /** @name Setting internal members | |
267 | @{ | |
268 | */ | |
269 | /** @brief Sets executable_name. | |
270 | ||
271 | \p argv_0 is stripped of its extension and path (if any) and the result is | |
272 | assigned to \c executable_name. | |
273 | ||
274 | @param argv_0 string containing the name of the program ( \c argv[0] ) | |
275 | */ | |
276 | static void set_executable_name(const char *argv_0); | |
277 | static inline char *get_executable_name() { return executable_name; } | |
278 | ||
279 | static data_log_format_t get_log_format() { return data_log_format; } | |
280 | static void set_log_format(data_log_format_t p_data_log_format) { data_log_format = p_data_log_format; } | |
281 | ||
282 | static bool add_parameter(const logging_setting_t& logging_param); | |
283 | static void set_plugin_parameters(component component_reference, const char* component_name); | |
284 | static void load_plugins(component component_reference, const char* component_name); | |
285 | ||
286 | /** @brief Set the log filename skeleton. | |
287 | ||
288 | @param new_filename_skeleton this string is copied to \c filename_skeleton | |
289 | @param from_config TRUE if set from config file value | |
290 | */ | |
291 | static void set_file_name(const char *new_filename_skeleton, | |
292 | boolean from_config = TRUE); | |
293 | ||
294 | /// Sets start_time by calling \c gettimeofday() | |
295 | static void set_start_time(); | |
296 | ||
297 | /** @brief Set the logging mask to a log file. | |
298 | ||
299 | The mask is simply stored internally. | |
300 | @see set_component() | |
301 | ||
302 | @param cmpt a component_id_t identifying the component. | |
303 | @param new_file_mask a \c LoggingBits containing the categories | |
304 | to be logged to a file. | |
305 | */ | |
306 | static void set_file_mask(component_id_t const& cmpt, | |
307 | const Logging_Bits& new_file_mask); | |
308 | ||
309 | /** @brief Set the logging mask to the console. | |
310 | ||
311 | The mask is simply stored internally. | |
312 | @see set_component() | |
313 | ||
314 | @param cmpt a component_id_t identifying the component. | |
315 | @param new_console_mask a \c LoggingBits containing the categories to be | |
316 | logged to the console. | |
317 | */ | |
318 | static void set_console_mask(component_id_t const& cmpt, | |
319 | const Logging_Bits& new_console_mask); | |
320 | ||
321 | /** @brief Set the logging mask to the console. | |
322 | ||
323 | The mask is simply stored internally. | |
324 | @see set_component() | |
325 | ||
326 | @param cmpt a component_id_t identifying the component. | |
327 | @param new_logging_mask | |
328 | */ | |
329 | static void set_emergency_logging_mask(component_id_t const& cmpt, | |
330 | const Logging_Bits& new_logging_mask); | |
331 | ||
332 | ||
333 | static Logging_Bits const& get_file_mask(); | |
334 | ||
335 | static Logging_Bits const& get_console_mask(); | |
336 | ||
337 | static Logging_Bits const& get_emergency_logging_mask(); | |
338 | ||
339 | static void set_timestamp_format(timestamp_format_t new_timestamp_format); | |
340 | static inline timestamp_format_t get_timestamp_format() | |
341 | { return timestamp_format; } | |
342 | static void set_source_info_format(source_info_format_t new_source_info_format); | |
343 | static inline source_info_format_t get_source_info_format() | |
344 | { return source_info_format; } | |
345 | static void set_log_event_types(log_event_types_t new_log_event_types); | |
346 | static inline log_event_types_t get_log_event_types() | |
347 | { return log_event_types; } | |
348 | static void set_append_file(boolean new_append_file); | |
349 | static void set_log_entity_name(boolean new_log_entity_name); | |
350 | /** @} */ | |
351 | ||
352 | static CHARSTRING get_timestamp_str(timestamp_format_t p_timestamp_format); | |
353 | static CHARSTRING get_source_info_str(source_info_format_t p_source_info_format); | |
354 | static boolean get_log_entity_name() { return log_entity_name; } | |
355 | static char *mputstr_severity(char *str, const TTCN_Logger::Severity& sev); | |
356 | static char *mputstr_timestamp(char *str, | |
357 | timestamp_format_t p_timestamp_format, | |
358 | const struct timeval *tv); | |
359 | // Register a logger plug-in into the LoggerPluginManager from the | |
360 | // configuration file. | |
361 | static void register_plugin(const component_id_t comp, char *identifier, char *filename); | |
362 | ||
363 | static bool set_file_size(component_id_t const& comp, int p_size); | |
364 | static bool set_file_number(component_id_t const& comp, int p_number); | |
365 | static bool set_disk_full_action(component_id_t const& comp, | |
366 | disk_full_action_t p_disk_full_action); | |
367 | ||
368 | /** @brief Whether a message with the given severity should be logged to the | |
369 | log file. | |
370 | ||
371 | Checks the actual logging bits selected by set_component() | |
372 | ||
373 | @param sev logging severity | |
374 | @return \c true if it should be logged, \c false otherwise | |
375 | */ | |
376 | static boolean should_log_to_file(Severity sev); | |
377 | ||
378 | /// Like should_log_to_file() but for logging to the console. | |
379 | static boolean should_log_to_console(Severity sev); | |
380 | ||
381 | /// Like should_log_to_file() but for logging to the emergency. | |
382 | static boolean should_log_to_emergency(Severity sev); | |
383 | ||
384 | /** @brief Get the log event mask. | |
385 | ||
386 | @deprecated Please use TTCN_Logger::should_log_to_file() or | |
387 | TTCN_Logger::should_log_to_console() instead. | |
388 | */ | |
389 | static unsigned int get_mask(); | |
390 | ||
391 | static matching_verbosity_t get_matching_verbosity(); | |
392 | static void set_matching_verbosity(matching_verbosity_t v); | |
393 | ||
394 | /** @brief Handle logging of the logger's configuration settings. | |
395 | ||
396 | This function is called from Single_main.cc and Runtime.cc immediately | |
397 | after the "Host controller/Executor/Component started" message. | |
398 | However, in some cases (e.g. in the HC) the logger's settings aren't known yet | |
399 | so the content of the log message cannot be determined. | |
400 | In this situation, an empty log message is stored until the configuration | |
401 | is received, then the stored message is updated before writing. | |
402 | This method performs all three of these operations. | |
403 | ||
404 | @param opening true if called from TTCN_Logger::open_file() while writing | |
405 | the buffered messages, false otherwise. | |
406 | */ | |
407 | static void write_logger_settings(bool opening = false); | |
408 | ||
409 | /** @brief Opens the log file. | |
410 | ||
411 | Opens the file with the name returned by get_filename(). If append_file | |
412 | is true, new events are written to the end of an existing log file. | |
413 | Otherwise, the log file is truncated. | |
414 | If there are buffered events, they are written to the file. | |
415 | */ | |
416 | static void open_file(); | |
417 | static void close_file(); | |
418 | /** @brief dump all events from ring buffer to log file | |
419 | @param do_close_file if true, close the files afterwards | |
420 | */ | |
421 | static void ring_buffer_dump(bool do_close_file); | |
422 | ||
423 | /** @brief Should this event be logged? | |
424 | ||
425 | @return \c true if the the event with severity specified by | |
426 | \p event_severity should be logged to either the console or the log file, | |
427 | \c false otherwise. | |
428 | ||
429 | If the logger was not configured yet, it returns true. Otherwise, it | |
430 | masks \p event_severity with console_mask and, if the log file is opened, | |
431 | file_mask. | |
432 | */ | |
433 | static boolean log_this_event(Severity event_severity); | |
434 | ||
435 | /** @brief Format and log a message. | |
436 | ||
437 | Calls log_va_list. | |
438 | ||
439 | @param msg_severity severity | |
440 | @param fmt_str printf-style format string | |
441 | @callgraph | |
442 | */ | |
443 | static void log(Severity msg_severity, const char *fmt_str, ...) | |
444 | __attribute__ ((__format__ (__printf__, 2, 3) /*, deprecated (one day) */ )); | |
445 | ||
446 | /** @brief Sends the current event string as an error message to the MC. | |
447 | */ | |
448 | static void send_event_as_error(); | |
449 | ||
450 | static void fatal_error(const char *err_msg, ...) | |
451 | __attribute__ ((__format__ (__printf__, 1, 2), | |
452 | __noreturn__)); | |
453 | ||
454 | /** @brief Log a string without formatting. | |
455 | ||
456 | Description: | |
457 | ||
458 | @param msg_severity severity | |
459 | @param str_ptr the string | |
460 | @callgraph | |
461 | */ | |
462 | static void log_str(Severity msg_severity, const char *str_ptr ); | |
463 | ||
464 | /** @brief Format and log a list of arguments. | |
465 | ||
466 | Description: | |
467 | ||
468 | @param msg_severity severity | |
469 | @param fmt_str printf-style format string | |
470 | @param p_var variable arguments | |
471 | @callgraph | |
472 | */ | |
473 | static void log_va_list(Severity msg_severity, const char *fmt_str, | |
474 | va_list p_var); | |
475 | ||
476 | /** @brief Begin an event | |
477 | ||
478 | Events are held on a stack; the new event becomes the current event. | |
479 | ||
480 | If the logger is not yet initialized, this function does nothing. | |
481 | ||
482 | @param msg_severity severity | |
483 | @callgraph | |
484 | */ | |
485 | static void begin_event(Severity msg_severity, boolean log2str = FALSE); | |
486 | ||
487 | /** begin an event that logs to CHARSTRING */ | |
488 | static void begin_event_log2str() { begin_event(USER_UNQUALIFIED, TRUE); } | |
489 | ||
490 | /** @brief End event | |
491 | ||
492 | @pre current_event != NULL | |
493 | ||
494 | This is when the event is actually logged. | |
495 | ||
496 | @callgraph | |
497 | */ | |
498 | static void end_event(); | |
499 | ||
500 | static CHARSTRING end_event_log2str(); | |
501 | ||
502 | /** @brief Finish event. | |
503 | ||
504 | @pre current_event != NULL | |
505 | ||
506 | @callgraph | |
507 | */ | |
508 | static void finish_event(); | |
509 | ||
510 | /** @brief Format a string into the current event. | |
511 | ||
512 | @pre current_event != NULL | |
513 | ||
514 | @param fmt_str printf-style format string | |
515 | @callgraph | |
516 | */ | |
517 | static void log_event(const char *fmt_str, ...) | |
518 | __attribute__ ((__format__ (__printf__, 1, 2))); | |
519 | ||
520 | /** @brief Log event str | |
521 | ||
522 | Stores a string in the current log event without formatting. | |
523 | ||
524 | @pre current_event != NULL | |
525 | ||
526 | @param str_ptr the message | |
527 | @callgraph | |
528 | */ | |
529 | static void log_event_str(const char *str_ptr); | |
530 | ||
531 | /** @brief Format a list of arguments into the current event. | |
532 | ||
533 | @pre current_event != NULL | |
534 | ||
535 | Increases the current event's buffer as needed. | |
536 | ||
537 | @param fmt_str printf-style format string | |
538 | @param p_var variable arguments | |
539 | @callgraph | |
540 | */ | |
541 | static void log_event_va_list(const char *fmt_str, va_list p_var); | |
542 | ||
543 | // Log an unbound/uninitialized/enum value according to the current format setting | |
544 | static void log_event_unbound(); | |
545 | static void log_event_uninitialized(); | |
546 | static void log_event_enum(const char* enum_name_str, int enum_value); | |
547 | ||
548 | /** @brief Log one character into the current event. | |
549 | ||
550 | @pre current_event != NULL | |
551 | ||
552 | Appends the character \c c to the buffer of the current event. | |
553 | ||
554 | @param c the character | |
555 | @callgraph | |
556 | */ | |
557 | static void log_char(char c); | |
558 | ||
559 | /// Return \c true if \c c is a printable character, \c false otherwise. | |
560 | static boolean is_printable(unsigned char c); | |
561 | ||
562 | /** @brief Log a char. | |
563 | ||
564 | Description: | |
565 | ||
566 | @param c the character | |
567 | @callgraph | |
568 | */ | |
569 | static void log_char_escaped(unsigned char c); | |
570 | ||
571 | /** @brief Log a char into expstring_t buffer. | |
572 | ||
573 | Description: | |
574 | ||
575 | @param c the character | |
576 | @param p_buffer expstring_t buffer | |
577 | @callgraph | |
578 | */ | |
579 | static void log_char_escaped(unsigned char c, char*& p_buffer); | |
580 | ||
581 | /** @brief Log hex. | |
582 | ||
583 | Description: | |
584 | ||
585 | @param nibble | |
586 | @callgraph | |
587 | */ | |
588 | static void log_hex(unsigned char nibble); | |
589 | ||
590 | /** @brief Log an octet. | |
591 | ||
592 | Description: | |
593 | ||
594 | @param octet | |
595 | @callgraph | |
596 | */ | |
597 | static void log_octet(unsigned char octet); | |
598 | ||
599 | /** @brief Synonymous to log_char. | |
600 | ||
601 | Description: | |
602 | ||
603 | @param c | |
604 | @callgraph | |
605 | */ | |
606 | static inline void log_event(char c) { log_char(c); } | |
607 | ||
608 | /** @brief Log the OS error based on the current errno. | |
609 | Description: | |
610 | @callgraph | |
611 | */ | |
612 | static void OS_error(); | |
613 | ||
614 | // To preserve the semantic meaning of the log messages... | |
615 | /** @name New, one-per-event log functions | |
616 | * @{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
617 | static void log_timer_read(const char *timer_name, double start_val); | |
618 | static void log_timer_start(const char *timer_name, double start_val); | |
619 | static void log_timer_guard(double start_val); | |
620 | static void log_timer_stop(const char *timer_name, double stop_val); | |
621 | static void log_timer_timeout(const char *timer_name, double timeout_val); | |
622 | static void log_timer_any_timeout(); | |
623 | static void log_timer_unqualified(const char *message); | |
624 | ||
625 | static void log_setverdict(verdicttype new_verdict, verdicttype old_verdict, | |
626 | verdicttype local_verdict, const char *old_reason = NULL, const char *new_reason = NULL); | |
627 | static void log_getverdict(verdicttype verdict); | |
628 | // Handle all VERDICTOP_FINAL events. ptc_verdict/new_verdict are used only | |
629 | // for detailed PTC statistics, in all other cases they're the same. | |
630 | // - is_ptc: true if we're setting the final verdict for a PTC, false for MTC | |
631 | // - ptc_verdict: final verdict of the PTC | |
632 | // - local_verdict: the local verdict until now | |
633 | // - new_verdict: new verdict after PTC is finished | |
634 | // - verdict_reason: final verdict reason for PTC/MTC if applicable | |
635 | // - notification: enumeration value for the two fixed notification messages | |
636 | // - ptc_compref: only for detailed PTC statistics | |
637 | // - ptc_name: only for detailed PTC statistics | |
638 | static void log_final_verdict(bool is_ptc, verdicttype ptc_verdict, | |
639 | verdicttype local_verdict, verdicttype new_verdict, | |
640 | const char *verdict_reason = NULL, int notification = -1, | |
641 | int ptc_compref = UNBOUND_COMPREF, const char *ptc_name = NULL); | |
642 | ||
643 | static void log_testcase_started (const qualified_name& testcase_name); | |
644 | static void log_testcase_finished(const qualified_name& testcase_name, | |
645 | verdicttype verdict, | |
646 | const char *reason); | |
647 | static void log_controlpart_start_stop(const char *module_name, int finished); | |
648 | static void log_controlpart_errors(unsigned int error_count); | |
649 | ||
650 | static void log_verdict_statistics(size_t none_count, double none_percent, | |
651 | size_t pass_count, double pass_percent, | |
652 | size_t inconc_count, double inconc_percent, | |
653 | size_t fail_count, double fail_percent, | |
654 | size_t error_count, double error_percent); | |
655 | ||
656 | static void log_defaultop_activate (const char *name, int id); | |
657 | static void log_defaultop_deactivate(const char *name, int id); | |
658 | static void log_defaultop_exit (const char *name, int id, int x); | |
659 | ||
660 | /// EXECUTOR_RUNTIME, fixed strings only (no params) | |
661 | static void log_executor_runtime(int reason); | |
662 | /// EXECUTOR_RUNTIME, messages with parameters | |
663 | static void log_HC_start(const char *host); | |
664 | static void log_fd_limits(int fd_limit, long fd_set_size); | |
665 | static void log_testcase_exec(const char *module, const char *tc); | |
666 | static void log_module_init(const char *module, bool finish = false); | |
667 | static void log_mtc_created(long pid); | |
668 | ||
669 | /// EXECUTOR_CONFIGDATA | |
670 | /// @param str module name, config file or NULL | |
671 | static void log_configdata(int reason, const char *str = NULL); | |
672 | ||
673 | static void log_executor_component(int reason); | |
674 | ||
675 | static void log_executor_misc(int reason, const char *name, const char *address, | |
676 | int port); | |
677 | ||
678 | static void log_extcommand(extcommand_t action, const char *cmd); | |
679 | //static void log_extcommand_success(const char *cmd); | |
680 | ||
681 | static void log_matching_done(const char *type, int ptc, | |
682 | const char *return_type, int reason); | |
683 | ||
684 | static void log_matching_problem(int reason, int operation, | |
685 | boolean check, boolean anyport, const char *port_name = NULL); | |
686 | ||
687 | static void log_matching_success(int port_type, const char *port_name, int compref, | |
688 | const CHARSTRING& info); | |
689 | static void log_matching_failure(int port_type, const char *port_name, int compref, | |
690 | int reason, const CHARSTRING& info); | |
691 | ||
692 | static void log_matching_timeout(const char *timer_name); | |
693 | ||
694 | static void log_portconnmap(int operation, int src_compref, const char *src_port, | |
695 | int dst_compref, const char *dst_port); | |
696 | ||
697 | static void log_par_ptc(int reason, | |
698 | const char *module = NULL, const char *name = NULL, int compref = 0, | |
699 | const char *compname = NULL, const char *tc_loc = NULL, | |
700 | int alive_pid = 0, int status = 0); | |
701 | ||
702 | static void log_port_queue(int operation, const char *port_name, int compref, | |
703 | int id, const CHARSTRING& address, const CHARSTRING& param); | |
704 | ||
705 | static void log_port_state(int operation, const char *port_name); | |
706 | ||
707 | static void log_procport_send(const char *portname, int operation, int compref, | |
708 | const CHARSTRING& system, const CHARSTRING& param); | |
709 | static void log_procport_recv(const char *portname, int operation, int compref, | |
710 | boolean check, const CHARSTRING& param, int id); | |
711 | static void log_msgport_send(const char *portname, int compref, | |
712 | const CHARSTRING& param); | |
713 | static void log_msgport_recv(const char *portname, int operation, int compref, | |
714 | const CHARSTRING& system, const CHARSTRING& param, int id); | |
715 | ||
716 | static void log_dualport_map(boolean incoming, const char *target_type, | |
717 | const CHARSTRING& value, int id); | |
718 | static void log_dualport_discard(boolean incoming, const char *target_type, | |
719 | const char *port_name, boolean unhaldled); | |
720 | ||
721 | static void log_port_misc(int reason, const char *port_name, | |
722 | int remote_component = NULL_COMPREF, const char *remote_port = NULL, | |
723 | const char *ip_address = NULL, int tcp_port = -1, int new_size = 0); | |
724 | ||
725 | static void log_random(int action, double v, unsigned long u); | |
726 | ||
727 | static void clear_parameters(); | |
728 | /** @} TODO: More * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
729 | }; | |
730 | ||
731 | /** @name #defines for backward-compatibility. | |
732 | These #defines (TTCN_ERROR, TTCN_WARNING, ... TTCN_DEBUG) | |
733 | are source-compatible (but \b not binary compatible) with the original #defines | |
734 | ||
735 | @note The values are not bit masks. Expressions like | |
736 | @code LOG_ALL | TTCN_DEBUG @endcode will not work correctly. | |
737 | ||
738 | @{ | |
739 | */ | |
740 | #define TTCN_ERROR TTCN_Logger::ERROR_UNQUALIFIED | |
741 | #define TTCN_WARNING TTCN_Logger::WARNING_UNQUALIFIED | |
742 | #define TTCN_PORTEVENT TTCN_Logger::PORTEVENT_UNQUALIFIED | |
743 | #define TTCN_TIMEROP TTCN_Logger::TIMEROP_UNQUALIFIED | |
744 | #define TTCN_VERDICTOP TTCN_Logger::VERDICTOP_UNQUALIFIED | |
745 | #define TTCN_DEFAULTOP TTCN_Logger::DEFAULTOP_UNQUALIFIED | |
746 | #define TTCN_ACTION TTCN_Logger::ACTION_UNQUALIFIED | |
747 | #define TTCN_TESTCASE TTCN_Logger::TESTCASE_UNQUALIFIED | |
748 | #define TTCN_FUNCTION TTCN_Logger::FUNCTION_UNQUALIFIED | |
749 | #define TTCN_USER TTCN_Logger::USER_UNQUALIFIED | |
750 | #define TTCN_STATISTICS TTCN_Logger::STATISTICS_UNQUALIFIED | |
751 | #define TTCN_PARALLEL TTCN_Logger::PARALLEL_UNQUALIFIED | |
752 | #define TTCN_EXECUTOR TTCN_Logger::EXECUTOR_UNQUALIFIED | |
753 | #define TTCN_MATCHING TTCN_Logger::MATCHING_UNQUALIFIED | |
754 | #define TTCN_DEBUG TTCN_Logger::DEBUG_UNQUALIFIED | |
755 | #define LOG_NOTHING TTCN_Logger::NOTHING_TO_LOG | |
756 | #define LOG_ALL TTCN_Logger::LOG_ALL_IMPORTANT | |
757 | /** @} */ | |
758 | ||
759 | extern TTCN_Logger TTCN_logger; | |
760 | ||
761 | class TTCN_Location { | |
762 | public: | |
763 | enum entity_type_t { LOCATION_UNKNOWN, LOCATION_CONTROLPART, | |
764 | LOCATION_TESTCASE, LOCATION_ALTSTEP, LOCATION_FUNCTION, | |
765 | LOCATION_EXTERNALFUNCTION, LOCATION_TEMPLATE }; | |
766 | protected: | |
767 | const char *file_name; | |
768 | unsigned int line_number; | |
769 | entity_type_t entity_type; | |
770 | const char *entity_name; | |
771 | TTCN_Location *inner_location, *outer_location; | |
772 | static TTCN_Location *innermost_location, *outermost_location; | |
773 | friend class LoggerPluginManager; | |
774 | public: | |
775 | /** @brief Create a TTCN_Location object. | |
776 | ||
777 | Objects of this class are created by code generated by the TTCN-3 compiler. | |
778 | ||
779 | @param par_file_name source file of the call site | |
780 | @param par_line_number line number of the call site | |
781 | @param par_entity_type controlpart/testcase/altstep/function/...etc | |
782 | @param par_entity_name entity name of the caller | |
783 | ||
784 | @note The constructor copies the par_file_name and par_entity_name | |
785 | pointers but not the strings. The caller must ensure that the strings | |
786 | don't go out of scope before the TTCN_Location object. | |
787 | */ | |
788 | TTCN_Location(const char *par_file_name, unsigned int par_line_number, | |
789 | entity_type_t par_entity_type = LOCATION_UNKNOWN, | |
790 | const char *par_entity_name = NULL); | |
791 | virtual ~TTCN_Location(); | |
792 | ||
793 | virtual void update_lineno(unsigned int new_lineno); | |
794 | ||
795 | /** @brief Write the current location information to a string. | |
796 | * | |
797 | * @param print_outers \c true to print all the callers | |
798 | * (in the style of SourceInfo = Stack) | |
799 | * @param print_innermost \c true to print the current (innermost) location | |
800 | * @param print_entity_name \c true to print the type | |
801 | * (control part/test case/altstep/function/template) and name | |
802 | * of the current location. | |
803 | * @note print_innermost is always TRUE (there is never a call with FALSE) | |
804 | * | |
805 | * @return an expstring_t. The caller is responsible for calling Free() | |
806 | **/ | |
807 | static char *print_location(boolean print_outers, boolean print_innermost, | |
808 | boolean print_entity_name); | |
809 | /** @brief Remove location information from a string. | |
810 | * | |
811 | * @param [in,out] par_str the string to modify. | |
812 | * @pre par_str was allocated by Malloc, or is NULL. | |
813 | * It may be an expstring_t. | |
814 | * | |
815 | * The function copies characters from \p par_str to a temporary string, | |
816 | * except characters between parentheses. Then it calls | |
817 | * \c Free(par_str) and replaces \p par_str with the temporary. | |
818 | * | |
819 | **/ | |
820 | static void strip_entity_name(char*& par_str); | |
821 | protected: | |
822 | char *append_contents(char *par_str, boolean print_entity_name) const; | |
823 | }; | |
824 | ||
825 | class TTCN_Location_Statistics: public TTCN_Location | |
826 | { | |
827 | public: | |
828 | TTCN_Location_Statistics(const char *par_file_name, unsigned int par_line_number, | |
829 | entity_type_t par_entity_type = LOCATION_UNKNOWN, | |
830 | const char *par_entity_name = NULL); | |
831 | ~TTCN_Location_Statistics(); | |
832 | void update_lineno(unsigned int new_lineno); | |
833 | static void init_file_lines(const char *file_name, const int line_nos[], size_t line_nos_len); | |
834 | static void init_file_functions(const char *file_name, const char *function_names[], size_t function_names_len); | |
835 | }; | |
836 | ||
837 | /// Restores the original log format when running out of scope: use as local variable | |
838 | class Logger_Format_Scope { | |
839 | private: | |
840 | TTCN_Logger::data_log_format_t orig_log_format; | |
841 | public: | |
842 | Logger_Format_Scope(TTCN_Logger::data_log_format_t p_log_format) { orig_log_format=TTCN_Logger::get_log_format(); TTCN_Logger::set_log_format(p_log_format); } | |
843 | ~Logger_Format_Scope() { TTCN_Logger::set_log_format(orig_log_format); } | |
844 | }; | |
845 | ||
846 | #endif |