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
36using 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
137PLUGIN_DESCRIPTION("Write BlackBoard interface data to files")
138EXPORT_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.