Fawkes API  Fawkes Development Version
bblogger_plugin.cpp
1 
2 /***************************************************************************
3  * bblogger_plugin.cpp - Fawkes BlackBoard Logger Plugin
4  *
5  * Created: Sat Nov 07 23:21:36 2009
6  * Copyright 2009 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "bblogger_plugin.h"
24 
25 #include "log_thread.h"
26 
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <utils/time/time.h>
30 
31 #include <cerrno>
32 #include <cstring>
33 #include <set>
34 #include <unistd.h>
35 
36 using namespace fawkes;
37 
38 /** @class BlackBoardLoggerPlugin "bblogger_plugin.h"
39  * BlackBoard logger plugin.
40  * This plugin logs one or more (or even all) interfaces to data files
41  * for later replay or analyzing.
42  *
43  * @author Tim Niemueller
44  */
45 
46 /** Constructor.
47  * @param config Fawkes configuration
48  */
50 {
51  std::set<std::string> ifaces;
52 
53  std::string prefix = "/fawkes/bblogger/";
54  std::string replay_prefix = "/fawkes/bblogreplay/";
55 
56  std::string scenario = "";
57  try {
58  scenario = config->get_string((prefix + "scenario").c_str());
59  } catch (Exception &e) {
60  e.append("No scenario defined, configure %sscenario", prefix.c_str());
61  throw;
62  }
63 
64  /*
65  bool generate_replay_config = false;
66  try {
67  generate_replay_config = config->get_bool((prefix + "generate_replay_config").c_str());
68  } catch (Exception &e) {} // ignored, use default set above
69  */
70 
71  std::string scenario_prefix = prefix + scenario + "/";
72  std::string ifaces_prefix = scenario_prefix + "interfaces/";
73 
74  std::string logdir = LOGDIR;
75  bool buffering = true;
76  bool flushing = false;
77  try {
78  logdir = config->get_string((scenario_prefix + "logdir").c_str());
79  } catch (Exception &e) { /* ignored, use default set above */
80  }
81  try {
82  buffering = config->get_bool((scenario_prefix + "buffering").c_str());
83  } catch (Exception &e) { /* ignored, use default set above */
84  }
85  try {
86  flushing = config->get_bool((scenario_prefix + "flushing").c_str());
87  } catch (Exception &e) { /* ignored, use default set above */
88  }
89 
90  struct stat s;
91  int err = stat(logdir.c_str(), &s);
92  if (err != 0) {
93  char buf[1024];
94  Exception se("Cannot access logdir %s (%s)", logdir.c_str(), strerror_r(errno, buf, 1024));
95  if (mkdir(logdir.c_str(), 0755) != 0) {
96  se.append("Failed to create log directory (%s)", strerror_r(errno, buf, 1024));
97  throw se;
98  }
99  } else if (!S_ISDIR(s.st_mode)) {
100  throw Exception("Logdir path %s is not a directory", logdir.c_str());
101  }
102 
103  // We do not have the framework clock available at this point, but for the start
104  // time of the log we are only interested in the system time anyway
105  Time start;
106 
107  char date[21];
108  Time now;
109  struct tm *tmp = localtime(&(now.get_timeval()->tv_sec));
110  strftime(date, 21, "%F-%H-%M-%S", tmp);
111  std::string replay_cfg_prefix = replay_prefix + scenario + "-" + date + "/logs/";
112 
113  Configuration::ValueIterator *i = config->search(ifaces_prefix.c_str());
114  while (i->next()) {
115  std::string iface_name = std::string(i->path()).substr(ifaces_prefix.length());
116  iface_name = iface_name.substr(0, iface_name.find("/"));
117 
118  //printf("Adding sync thread for peer %s\n", peer.c_str());
119  BBLoggerThread *log_thread = new BBLoggerThread(
120  i->get_string().c_str(), logdir.c_str(), buffering, flushing, scenario.c_str(), &start);
121 
122  std::string filename = log_thread->get_filename();
123  config->set_string((replay_cfg_prefix + iface_name + "/file").c_str(), filename);
124 
125  thread_list.push_back(log_thread);
126  }
127  delete i;
128 
129  if (thread_list.empty()) {
130  throw Exception("No interfaces configured for logging, aborting");
131  }
132 
133  BBLoggerThread *bblt = dynamic_cast<BBLoggerThread *>(thread_list.front());
135 }
136 
137 PLUGIN_DESCRIPTION("Write BlackBoard interface data to files")
138 EXPORT_PLUGIN(BlackBoardLoggerPlugin)
BlackBoard logger thread.
Definition: log_thread.h:52
const char * get_filename() const
Get filename.
Definition: log_thread.cpp:221
void set_threadlist(fawkes::ThreadList &thread_list)
Set threadlist and master status.
Definition: log_thread.cpp:253
BlackBoard logger plugin.
BlackBoardLoggerPlugin(fawkes::Configuration *config)
Constructor.
Iterator interface to iterate over config values.
Definition: config.h:75
virtual const char * path() const =0
Path of value.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual std::string get_string() const =0
Get string value.
Interface for configuration handling.
Definition: config.h:68
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
virtual void set_string(const char *path, std::string &s)=0
Set new value in configuration of type string.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
Base class for exceptions in Fawkes.
Definition: exception.h:36
void append(const char *format,...) noexcept
Append messages to the message list.
Definition: exception.cpp:333
Plugin interface class.
Definition: plugin.h:34
ThreadList thread_list
Thread list member.
Definition: plugin.h:53
Configuration * config
Fawkes configuration.
Definition: plugin.h:58
void push_back(Thread *thread)
Add thread to the end.
A class for handling time.
Definition: time.h:93
const timeval * get_timeval() const
Obtain the timeval where the time is stored.
Definition: time.h:112
Fawkes library namespace.