Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 Ericsson Telecom AB | |
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 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Beres, Szabolcs | |
11 | * Kovacs, Ferenc | |
12 | * Raduly, Csaba | |
13 | * Szabados, Kristof | |
14 | * Zalanyi, Balazs Andor | |
15 | * Pandi, Krisztian | |
16 | * | |
17 | ******************************************************************************/ | |
970ed795 EL |
18 | #ifndef LOGGER_PLUGIN_MANAGER_HH |
19 | #define LOGGER_PLUGIN_MANAGER_HH | |
20 | ||
21 | #include "Types.h" | |
22 | #include "Logger.hh" | |
23 | #include "LoggerPlugin.hh" | |
24 | #include "TitanLoggerApi.hh" | |
25 | // The above includes TTCN3.hh, which pulls in everything in the runtime | |
26 | #include "LoggingParam.hh" | |
27 | ||
28 | struct Logging_Bits; | |
29 | struct component_id_t; | |
30 | struct disk_full_action_t; | |
31 | ||
32 | #ifdef __GNUC__ | |
33 | #define MUST_CHECK __attribute__((__warn_unused_result__)) | |
34 | #else | |
35 | #define MUST_CHECK | |
36 | #endif | |
37 | ||
38 | namespace LoggerAPI | |
39 | { | |
40 | class TitanLogEvent; | |
41 | } | |
42 | ||
43 | ||
44 | class RingBuffer | |
45 | { | |
46 | TitanLoggerApi::TitanLogEvent* buffer; | |
47 | unsigned int head; | |
48 | unsigned int tail; | |
49 | unsigned int size; | |
50 | ||
51 | public: | |
52 | explicit RingBuffer() : buffer(NULL), head(0), tail(0), | |
53 | size(TTCN_Logger::get_emergency_logging()) {} | |
54 | ~RingBuffer(); | |
55 | ||
56 | bool get(TitanLoggerApi::TitanLogEvent& data) MUST_CHECK; | |
57 | void put(TitanLoggerApi::TitanLogEvent data); | |
58 | void clear(); | |
59 | unsigned int get_size() const { return size; } | |
60 | void set_size(unsigned int new_size); | |
61 | bool isFull() const { return (head + 1) % (size + 1) == tail; } | |
62 | bool isEmpty() const {return head == tail; } | |
63 | }; | |
64 | ||
65 | class LoggerPluginManager | |
66 | { | |
67 | friend class ILoggerPlugin; | |
68 | ||
69 | public: | |
70 | void ring_buffer_dump(bool do_close_file); | |
71 | ||
72 | // Sends a single log event to all logger plugins. | |
73 | void internal_log_to_all(const TitanLoggerApi::TitanLogEvent& event, | |
74 | bool log_buffered, bool separate_file, bool use_emergency_mask); | |
75 | // If an event appears before any logger is configured we have to pre-buffer it. | |
76 | void internal_prebuff_logevent(const TitanLoggerApi::TitanLogEvent& event); | |
77 | // When the loggers get configured we have to log everything we have buffered so far | |
78 | void internal_log_prebuff_logevent(); | |
79 | public: | |
80 | explicit LoggerPluginManager(); | |
81 | ~LoggerPluginManager(); | |
82 | ||
83 | void register_plugin(const component_id_t comp, char *identifier, char *filename); | |
84 | void load_plugins(component component_reference, const char *component_name); | |
85 | void unload_plugins(); | |
86 | void reset(); | |
87 | ||
88 | bool add_parameter(const logging_setting_t& logging_param); | |
89 | void set_parameters(component component_reference, const char *component_name); | |
90 | ||
91 | bool plugins_ready() const; | |
92 | ||
93 | /// Backward compatibility functions to handle top level configuration file | |
94 | /// parameters. All logger plug-ins will receive these settings, but they | |
95 | /// can simply ignore them. | |
96 | bool set_file_mask(component_id_t const& comp, const Logging_Bits& new_file_mask); | |
97 | bool set_console_mask(component_id_t const& comp, | |
98 | const Logging_Bits& new_console_mask); | |
99 | void set_file_name(const char *new_filename_skeleton, bool from_config); | |
100 | void set_append_file(bool new_append_file); | |
101 | /// Return true if the given configuration file parameter was set multiple | |
102 | /// times. (The return value is used by the configuration file parser.) | |
103 | bool set_file_size(component_id_t const& comp, int p_size); | |
104 | bool set_file_number(component_id_t const& cmpt, int p_number); | |
105 | bool set_disk_full_action(component_id_t const& comp, | |
106 | TTCN_Logger::disk_full_action_t p_disk_full_action); | |
107 | void open_file(); | |
108 | void close_file(); | |
109 | void fill_common_fields(TitanLoggerApi::TitanLogEvent& event, | |
110 | const TTCN_Logger::Severity& severity); | |
111 | void append_event_str(const char *str); | |
112 | ||
113 | /// returns a copy of the current event string | |
114 | char* get_current_event_str(); | |
115 | ||
116 | /// Do the actual call to the plug-ins with EVENT. Flush the buffers if | |
117 | /// necessary. It is called at the end of each log_* function. The | |
118 | /// complete event handling is part of LoggerPluginManager. | |
119 | void log(const TitanLoggerApi::TitanLogEvent& event); | |
120 | void log_va_list(TTCN_Logger::Severity msg_severity, const char *fmt_str, | |
121 | va_list p_var); | |
122 | void buffer_event(const TitanLoggerApi::TitanLogEvent& event); | |
123 | void begin_event(TTCN_Logger::Severity msg_severity, bool log2str); | |
124 | void end_event(); | |
125 | CHARSTRING end_event_log2str(); | |
126 | void finish_event(); | |
127 | void log_event_str(const char *str_ptr); | |
128 | void log_char(char c); | |
129 | void log_event_va_list(const char *fmt_str, va_list p_var); | |
130 | void log_unhandled_event(TTCN_Logger::Severity severity, | |
131 | const char *message_ptr, size_t message_len); | |
132 | void log_log_options(const char *message_ptr, size_t message_len); | |
133 | ||
134 | /** @name New, one-per-event log functions. | |
135 | * @{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
136 | void log_timer_read(const char *timer_name, double start_val); | |
137 | void log_timer_start(const char *timer_name, double start_val); | |
138 | void log_timer_guard(double start_val); | |
139 | void log_timer_stop(const char *timer_name, double stop_val); | |
140 | void log_timer_timeout(const char *timer_name, double timeout_val); | |
141 | void log_timer_any_timeout(); | |
142 | void log_timer_unqualified(const char *message); | |
143 | ||
144 | void log_testcase_started (const qualified_name& testcase_name); | |
145 | void log_testcase_finished(const qualified_name& testcase_name, | |
146 | verdicttype verdict, const char *reason); | |
147 | ||
148 | void log_controlpart_start_stop(const char *module_name, int finished); | |
149 | void log_controlpart_errors(unsigned int error_count); | |
150 | ||
151 | void log_setverdict(verdicttype new_verdict, verdicttype old_verdict, | |
152 | verdicttype local_verdict, const char *old_reason = NULL, const char *new_reason = NULL); | |
153 | void log_getverdict(verdicttype verdict); | |
154 | void log_final_verdict(bool is_ptc, verdicttype ptc_verdict, | |
155 | verdicttype local_verdict, verdicttype new_verdict, | |
156 | const char *verdict_reason = NULL, int notification = -1, | |
157 | int ptc_compref = UNBOUND_COMPREF, const char *ptc_name = NULL); | |
158 | ||
159 | void log_verdict_statistics(size_t none_count, double none_percent, | |
160 | size_t pass_count, double pass_percent, | |
161 | size_t inconc_count, double inconc_percent, | |
162 | size_t fail_count, double fail_percent, | |
163 | size_t error_count, double error_percent); | |
164 | ||
165 | void log_defaultop_activate (const char *name, int id); | |
166 | void log_defaultop_deactivate(const char *name, int id); | |
167 | void log_defaultop_exit (const char *name, int id, int x); | |
168 | ||
169 | /// EXECUTOR_RUNTIME, fixed strings only (no params) | |
170 | void log_executor_runtime(TitanLoggerApi::ExecutorRuntime_reason reason); | |
171 | // EXECUTOR_RUNTIME with parameters | |
172 | void log_HC_start(const char *host); | |
173 | void log_fd_limits(int fd_limit, long fd_set_size); | |
174 | void log_not_overloaded(int pid); | |
175 | void log_testcase_exec(const char *tc, const char *module); | |
176 | void log_module_init(const char *module, bool finish); | |
177 | void log_mtc_created(long pid); | |
178 | /// EXECUTOR_CONFIGDATA | |
179 | void log_configdata(int reason, const char *str); | |
180 | ||
181 | void log_executor_component(int reason); // and some more | |
182 | ||
183 | void log_executor_misc(int reason, const char *name, const char *address, | |
184 | int port); | |
185 | ||
186 | void log_extcommand(TTCN_Logger::extcommand_t action, const char *cmd); | |
187 | ||
188 | void log_matching_done(TitanLoggerApi::MatchingDoneType_reason reason, | |
189 | const char *type, int ptc, const char *return_type); | |
190 | ||
191 | void log_matching_problem(int reason, int operation, | |
192 | boolean check, boolean anyport, const char *port_name); | |
193 | ||
194 | void log_matching_success(int port_type, const char *port_name, int compref, | |
195 | const CHARSTRING& info); | |
196 | void log_matching_failure(int port_type, const char *port_name, int compref, | |
197 | int reason, const CHARSTRING& info); | |
198 | ||
199 | void log_matching_timeout(const char *timer_name); | |
200 | ||
201 | void log_random(int action, double v, unsigned long u); | |
202 | ||
203 | void log_portconnmap(int operation, int src_compref, const char *src_port, | |
204 | int dst_compref, const char *dst_port); | |
205 | ||
206 | void log_par_ptc(int reason, const char *module, const char *name, int compref, | |
207 | const char *compname, const char *tc_loc, int alive_pid, int status); | |
208 | ||
209 | void log_port_queue(int operation, const char *port_name, int compref, int id, | |
210 | const CHARSTRING& address, const CHARSTRING& param); | |
211 | ||
212 | void log_port_state(int operation, const char *port_name); | |
213 | ||
214 | void log_procport_send(const char *portname, int operation, | |
215 | int compref, const CHARSTRING& system, const CHARSTRING& param); | |
216 | void log_procport_recv(const char *portname, int operation, int compref, | |
217 | boolean check, const CHARSTRING& param, int id); | |
218 | void log_msgport_send(const char *portname, int compref, | |
219 | const CHARSTRING& param); | |
220 | void log_msgport_recv(const char *portname, int operation, int compref, | |
221 | const CHARSTRING& system, const CHARSTRING& param, int id); | |
222 | ||
223 | void log_dualport_map(boolean incoming, const char *target_type, | |
224 | const CHARSTRING& value, int id); | |
225 | void log_dualport_discard(boolean incoming, const char *target_type, | |
226 | const char *port_name, boolean unhandled); | |
227 | ||
228 | void log_port_misc(int reason, const char *port_name, int remote_component, | |
229 | const char *remote_port, const char *ip_address, int tcp_port, int new_size); | |
230 | ||
231 | /** @} * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
232 | LoggerPlugin *find_plugin(const char *name); | |
233 | ||
234 | void clear_param_list(); | |
235 | void clear_plugin_list(); | |
236 | ||
237 | private: | |
238 | explicit LoggerPluginManager(const LoggerPluginManager&); | |
239 | LoggerPluginManager& operator=(const LoggerPluginManager&); | |
240 | ||
241 | void apply_parameter(const logging_setting_t& logparam); | |
242 | void send_parameter_to_plugin(LoggerPlugin* plugin, const logging_setting_t& logparam); | |
243 | ||
244 | void load_plugin(const char *identifier, const char *filename); | |
245 | ||
246 | enum event_destination_t | |
247 | { | |
248 | ED_NONE, // To be discarded. | |
249 | ED_FILE, // Event goes to log file or console, it's a historic name. | |
250 | ED_STRING // Event goes to CHARSTRING. | |
251 | }; | |
252 | ||
253 | private: | |
254 | /// Circular buffer for emergency logging | |
255 | RingBuffer ring_buffer; | |
256 | ||
257 | /// Number of loaded plug-ins. Should be at least 1. | |
258 | size_t n_plugins_; | |
259 | ||
260 | /// List of active (dynamic/static) logger plug-ins. | |
261 | LoggerPlugin **plugins_; | |
262 | ||
263 | // This is for the fast events. | |
264 | struct LogEntry | |
265 | { | |
266 | TitanLoggerApi::TitanLogEvent event_; | |
267 | LogEntry *next_entry_; | |
268 | } *entry_list_; | |
269 | ||
270 | // This is for the active events (~ stack). | |
271 | struct ActiveEvent | |
272 | { | |
273 | /// Space for a TitanLogEvent aligned as a long int. | |
274 | long event_[(sizeof(TitanLoggerApi::TitanLogEvent) - 1 + sizeof(long)) | |
275 | / sizeof(long)]; | |
276 | ||
277 | char *event_str_; // Speed up event string handling. | |
278 | size_t event_str_len_; ///< Actual length of the string. | |
279 | size_t event_str_size_; ///< Size of the allocated memory. | |
280 | event_destination_t event_destination_; // Used only be active events. | |
281 | ActiveEvent *outer_event_; | |
282 | // For better space efficiency, all the pieces are kept concatenated as always, | |
283 | // but we remember offsets into the concatenated string. | |
284 | size_t num_pieces_; | |
285 | size_t *pieces_; // the end of each piece | |
286 | // Only (num_pieces_-1) elements are allocated, so the last accessible | |
287 | // element is at num_pieces_-2. The end of the last piece is event_str_len_ | |
288 | ||
289 | /// True if the event is for log2str, in which case @p event_ is blank. | |
290 | bool fake_; | |
291 | ||
292 | /** Constructor | |
293 | * | |
294 | * @param fake_event true if the event is for log2str, in which case | |
295 | * @p event_ is not initialized. | |
296 | * @param dest event destination (logfile, string or none) | |
297 | */ | |
298 | ActiveEvent(bool fake_event, event_destination_t dest); | |
299 | ~ActiveEvent(); | |
300 | TitanLoggerApi::TitanLogEvent& get_event() | |
301 | { | |
302 | return *reinterpret_cast<TitanLoggerApi::TitanLogEvent*>((void*)&event_); | |
303 | } | |
304 | } *current_event_; | |
305 | ||
306 | logging_setting_t* logparams_head; | |
307 | logging_setting_t* logparams_tail; | |
308 | ||
309 | logging_plugin_t* logplugins_head; | |
310 | logging_plugin_t* logplugins_tail; | |
311 | }; | |
312 | ||
313 | #endif // LOGGER_PLUGIN_MANAGER_HH |