23 #include "log_thread.h"
26 #include <blackboard/blackboard.h>
27 #include <logging/logger.h>
28 #include <core/exceptions/system.h>
29 #include <interfaces/SwitchInterface.h>
38 # include <sys/endian.h>
39 #elif defined(__MACH__) && defined(__APPLE__)
40 # include <sys/_endian.h>
44 #include <arpa/inet.h>
48 using namespace fawkes;
78 const char *logdir,
bool buffering,
bool flushing,
80 :
Thread(
"BBLoggerThread",
Thread::OPMODE_WAITFORWAKEUP),
84 set_name(
"BBLoggerThread(%s)", iface_uid);
86 __buffering = buffering;
87 __flushing = flushing;
88 __uid = strdup(iface_uid);
89 __logdir = strdup(logdir);
90 __scenario = strdup(scenario);
91 __start =
new Time(start_time);
93 __queue_mutex =
new Mutex();
101 Interface::parse_uid(__uid, &__type, &__id);
105 struct tm *tmp = localtime(&(now.
get_timeval()->tv_sec));
106 strftime(date, 21,
"%F-%H-%M-%S", tmp);
108 if (asprintf(&__filename,
"%s/%s-%s-%s-%s.log", LOGDIR, __scenario,
109 __type, __id, date) == -1) {
124 delete __queue_mutex;
136 __queue_mutex =
new Mutex();
140 __num_data_items = 0;
145 mode_t m = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
146 int fd = open(__filename, O_RDWR | O_CREAT | O_EXCL, m);
150 __f_data = fdopen(fd,
"w+");
178 __switch_if->
write();
192 __is_master ?
" as master" :
"");
205 for (
unsigned int q = 0; q < 2; ++q) {
206 while (!__queues[q].empty()) {
207 void *t = __queues[q].front();
234 if (enabled && !__enabled) {
236 (__num_data_items - __session_start));
237 __session_start = __num_data_items;
238 }
else if (!enabled && __enabled) {
240 (__num_data_items - __session_start));
259 __threads = thread_list;
263 BBLoggerThread::write_header()
266 memset(&header, 0,
sizeof(header));
267 header.
file_magic = htonl(BBLOGGER_FILE_MAGIC);
269 #if __BYTE_ORDER == __BIG_ENDIAN
275 strncpy(header.
scenario, (
const char *)__scenario, BBLOG_SCENARIO_SIZE);
277 strncpy(header.
interface_id, __iface->
id(), BBLOG_INTERFACE_ID_SIZE);
280 long start_time_sec, start_time_usec;
284 if (fwrite(&header,
sizeof(header), 1, __f_data) != 1) {
292 BBLoggerThread::update_header()
295 #if _POSIX_MAPPED_FILES
297 fileno(__f_data), 0);
298 if (h == MAP_FAILED) {
300 "not updating number of data items",
309 "not updating number of data items on close");
314 BBLoggerThread::write_chunk(
const void *chunk)
318 Time d = *__now - *__start;
319 long rel_time_sec, rel_time_usec;
323 if ( (fwrite(&ehead,
sizeof(ehead), 1, __f_data) == 1) &&
324 (fwrite(chunk, __data_size, 1, __f_data) == 1) ) {
325 if (__flushing) fflush(__f_data);
326 __num_data_items += 1;
336 unsigned int write_queue = __act_queue;
337 __queue_mutex->
lock();
338 __act_queue = 1 - __act_queue;
342 while (! queue.empty() ) {
343 void *c = queue.front();
358 if ((enm = dynamic_cast<SwitchInterface::EnableSwitchMessage *>(message)) != NULL) {
360 }
else if ((dism = dynamic_cast<SwitchInterface::DisableSwitchMessage *>(message)) != NULL) {
363 logger->
log_debug(name(),
"Unhandled message type: %s via %s",
364 message->type(), interface->uid());
367 for (ThreadList::iterator i = __threads.begin(); i != __threads.end(); ++i) {
372 __switch_if->set_enabled(__enabled);
373 __switch_if->write();
382 if (!__enabled)
return;
388 void *c = malloc(__iface->datasize());
389 memcpy(c, __iface->datachunk(), __iface->datasize());
390 __queue_mutex->lock();
391 __queues[__act_queue].push_locked(c);
392 __queue_mutex->unlock();
395 __queue_mutex->lock();
396 write_chunk(__iface->datachunk());
397 __queue_mutex->unlock();
401 logger->
log_error(name(),
"Exception when data changed");
408 unsigned int instance_serial)
throw()
410 __session_start = __num_data_items;
415 unsigned int instance_serial)
throw()
417 logger->
log_info(name(),
"Writer removed (wrote %u entries), flushing",
418 (__num_data_items - __session_start));
File could not be opened.
virtual bool bb_interface_message_received(fawkes::Interface *interface, fawkes::Message *message)
BlackBoard message received notification.
void clear()
Clear the queue.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
virtual void log_error(const char *component, const char *format,...)
Log error message.
const timeval * get_timeval() const
Obtain the timeval where the time is stored.
void unlock()
Unlock the mutex.
void bbil_add_writer_interface(Interface *interface)
Add an interface to the writer addition/removal watch list.
virtual void finalize()
Finalize the thread.
const unsigned char * hash() const
Get interface hash.
A class for handling time.
virtual void init()
Initialize the thread.
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Thread class encapsulation of pthreads.
void write()
Write from local copy into BlackBoard memory.
Base class for all Fawkes BlackBoard interfaces.
virtual ~BBLoggerThread()
Destructor.
BlackBoard logger thread.
Logger * logger
This is the Logger member used to access the logger.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier)=0
Open interface for writing.
const char * uid() const
Get unique identifier of interface.
virtual void bb_interface_writer_added(fawkes::Interface *interface, unsigned int instance_serial)
A writing instance has been opened for a watched interface.
Clock * clock
By means of this member access to the clock is given.
const char * id() const
Get identifier of interface.
virtual void bb_interface_data_changed(fawkes::Interface *interface)
BlackBoard data changed notification.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
SwitchInterface Fawkes BlackBoard Interface.
unsigned int datasize() const
Get data size.
void set_name(const char *format,...)
Set name of thread.
Base class for exceptions in Fawkes.
virtual void bb_interface_writer_removed(fawkes::Interface *interface, unsigned int instance_serial)
A writing instance has been closed for a watched interface.
void set_enabled(const bool new_enabled)
Set enabled value.
DisableSwitchMessage Fawkes BlackBoard Interface Message.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
void get_timestamp(long &sec, long &usec) const
Get time stamp.
void set_coalesce_wakeups(bool coalesce=true)
Set wakeup coalescing.
void set_enabled(bool enabled)
Enable or disable logging.
const char * name() const
Get name of thread.
virtual void loop()
Code to execute in the thread.
BBLoggerThread(const char *iface_uid, const char *logdir, bool buffering, bool flushing, const char *scenario, fawkes::Time *start_time)
Constructor.
void set_threadlist(fawkes::ThreadList &thread_list)
Set threadlist and master status.
virtual void log_info(const char *component, const char *format,...)
Log informational message.
EnableSwitchMessage Fawkes BlackBoard Interface Message.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier)=0
Open interface for reading.
void lock()
Lock this mutex.
Time & stamp()
Set this time to the current time.
const char * get_filename() const
Get filename.
Mutex mutual exclusion lock.
void bbil_add_message_interface(Interface *interface)
Add an interface to the message received watch list.
const char * type() const
Get type of interface.
virtual void log_debug(const char *component, const char *format,...)
Log debug message.
System ran out of memory and desired operation could not be fulfilled.
BlackBoard interface listener.
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
void bbil_add_data_interface(Interface *interface)
Add an interface to the data modification watch list.
virtual void close(Interface *interface)=0
Close interface.