23 #include "log_thread.h"
27 #include <blackboard/blackboard.h>
28 #include <core/exceptions/system.h>
29 #include <interfaces/SwitchInterface.h>
30 #include <logging/logger.h>
39 # include <sys/endian.h>
40 #elif defined(__MACH__) && defined(__APPLE__)
41 # include <sys/_endian.h>
45 #include <arpa/inet.h>
82 const char * scenario,
84 :
Thread(
"BBLoggerThread",
Thread::OPMODE_WAITFORWAKEUP),
88 set_name(
"BBLoggerThread(%s)", iface_uid);
90 buffering_ = buffering;
92 uid_ = strdup(iface_uid);
93 logdir_ = strdup(logdir);
94 scenario_ = strdup(scenario);
95 start_ =
new Time(start_time);
97 queue_mutex_ =
new Mutex();
105 Interface::parse_uid(uid_, type_, id_);
109 struct tm *tmp = localtime(&(now.
get_timeval()->tv_sec));
110 strftime(date, 21,
"%F-%H-%M-%S", tmp);
113 &filename_,
"%s/%s-%s-%s-%s.log", LOGDIR, scenario_, type_.c_str(), id_.c_str(), date)
137 queue_mutex_ =
new Mutex();
146 mode_t m = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
147 int fd = open(filename_, O_RDWR | O_CREAT | O_EXCL, m);
151 f_data_ = fdopen(fd,
"w+");
193 name(),
"Logging %s to %s%s", iface_->
uid(), filename_, is_master_ ?
" as master" :
"");
205 for (
unsigned int q = 0; q < 2; ++q) {
206 while (!queues_[q].empty()) {
207 void *t = queues_[q].front();
232 if (enabled && !enabled_) {
234 session_start_ = num_data_items_;
235 }
else if (!enabled && enabled_) {
237 "Logging disabled (wrote %u entries), flushing",
238 (num_data_items_ - session_start_));
256 threads_ = thread_list;
260 BBLoggerThread::write_header()
263 memset(&header, 0,
sizeof(header));
264 header.
file_magic = htonl(BBLOGGER_FILE_MAGIC);
266 #if BYTE_ORDER_ == BIG_ENDIAN_
272 strncpy(header.
scenario, (
const char *)scenario_, BBLOG_SCENARIO_SIZE - 1);
274 strncpy(header.
interface_id, iface_->
id(), BBLOG_INTERFACE_ID_SIZE - 1);
277 long start_time_sec, start_time_usec;
281 if (fwrite(&header,
sizeof(header), 1, f_data_) != 1) {
289 BBLoggerThread::update_header()
292 #if _POSIX_MAPPED_FILES
293 void *h = mmap(NULL,
sizeof(
bblog_file_header), PROT_WRITE, MAP_SHARED, fileno(f_data_), 0);
294 if (h == MAP_FAILED) {
296 "Failed to mmap log (%s), "
297 "not updating number of data items",
306 "Memory mapped files not available, "
307 "not updating number of data items on close");
312 BBLoggerThread::write_chunk(
const void *chunk)
316 Time d = *now_ - *start_;
317 long rel_time_sec, rel_time_usec;
321 if ((fwrite(&ehead,
sizeof(ehead), 1, f_data_) == 1)
322 && (fwrite(chunk, data_size_, 1, f_data_) == 1)) {
325 num_data_items_ += 1;
334 unsigned int write_queue = act_queue_;
335 queue_mutex_->
lock();
336 act_queue_ = 1 - act_queue_;
340 while (!queue.empty()) {
341 void *c = queue.front();
361 "Unhandled message type: %s via %s",
366 for (ThreadList::iterator i = threads_.begin(); i != threads_.end(); ++i) {
371 switch_if_->set_enabled(enabled_);
387 void *c = malloc(iface_->datasize());
388 memcpy(c, iface_->datachunk(), iface_->datasize());
389 queue_mutex_->lock();
390 queues_[act_queue_].push_locked(c);
391 queue_mutex_->unlock();
394 queue_mutex_->lock();
395 write_chunk(iface_->datachunk());
396 queue_mutex_->unlock();
400 logger->
log_error(name(),
"Exception when data changed");
407 unsigned int instance_serial)
throw()
409 session_start_ = num_data_items_;
414 unsigned int instance_serial)
throw()
417 "Writer removed (wrote %u entries), flushing",
418 (num_data_items_ - session_start_));