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