23 #include "../bblogfile.h" 25 #include <utils/system/argparser.h> 26 #include <utils/system/signal.h> 27 #include <utils/time/time.h> 28 #include <utils/system/fam.h> 30 #include <blackboard/remote.h> 31 #include <blackboard/internal/instance_factory.h> 32 #include <interfaces/SwitchInterface.h> 38 #include <arpa/inet.h> 39 #include <sys/types.h> 47 print_usage(
const char *program_name)
49 printf(
"Usage: %s [-h] [-r host:port] <COMMAND> <logfile>\n" 50 " %s print <logfile> <index> [index ...]\n" 51 " %s convert <infile> <outfile> <format>\n" 53 " -h Print this usage information\n" 55 " watch Continuously watch a log file (like tail)\n" 56 " info Print meta information of log file\n" 57 " print Print specific data index\n" 58 " <index> [index ...] is a list of indices to print\n" 59 " replay Replay log file in real-time to console\n" 60 " repair Repair file, i.e. properly set number of entries\n" 61 " enable Enable logging on a remotely running bblogger\n" 62 " disable Disable logging on a remotely running bblogger\n" 63 " convert Convert logfile to different format\n" 64 " <infile> input log file\n" 65 " <outfile> converted output file\n" 66 " <format> format to convert to, currently supported:\n" 67 " - csv Comma-separated values\n",
68 program_name, program_name, program_name);
73 print_info(std::string &filename)
80 printf(
"Failed to print info, exception follows\n");
87 repair_file(std::string &filename)
91 printf(
"Nothing to repair, files are fine\n");
94 if (strcmp(e.
type_id(),
"repair-success") == 0) {
95 printf(
"Repair successful, actions done follow.\n");
99 printf(
"Repair failed, exception follows.\n");
107 print_indexes(std::string &filename, std::vector<unsigned int> &indexes)
111 for (
unsigned int i = 0; i < indexes.size(); ++i) {
117 printf(
"Failed to print info, exception follows\n");
126 replay_file(std::string &filename)
131 Time last_offset((
long)0);
133 if (! bf.has_next()) {
134 printf(
"File does not have any entries, aborting.\n");
142 last_offset = bf.entry_offset();
145 while (bf.has_next()) {
147 diff = bf.entry_offset() - last_offset;
149 last_offset = bf.entry_offset();
154 printf(
"Failed to print info, exception follows\n");
168 BBLogWatcher(
const char *filename,
BBLogFile &file)
173 __fam->add_listener(
this);
174 __fam->watch_file(filename);
180 __fam->remove_listener(
this);
184 virtual void fam_event(
const char *filename,
unsigned int mask)
186 if (mask & FAM_DELETE) {
190 unsigned int remaining = __file.remaining_entries();
191 for (
unsigned int i = 0; i < remaining; ++i) {
193 __file.print_entry();
198 virtual void handle_signal(
int signal)
207 __fam->process_events(-1);
219 watch_file(std::string &filename)
221 BBLogFile file(filename.c_str(), NULL,
false);
226 BBLogWatcher watcher(filename.c_str(), file);
234 set_enabled(
const char *hostname,
unsigned short int port,
bool enabled)
241 printf(
"No writer exists, BBLogger not loaded?\n");
259 convert_file_csv(
BBLogFile &bf, FILE *outf)
264 fprintf(outf,
"# Time relative to beginning (in sec)");
267 fprintf(outf,
";%s (%s[%zu])",
278 fprintf(outf,
";%s", i.get_value_string());
286 convert_file(std::string &infile, std::string &outfile, std::string &format)
288 if (format !=
"csv") {
289 printf(
"Unsupported output format '%s'\n", format.c_str());
293 FILE *outf = fopen(outfile.c_str(),
"wx");
295 perror(
"Failed to open output file");
303 if (format ==
"csv") {
304 convert_file_csv(bf, outf);
308 printf(
"Failed to convert log file: %s\n", e.
what());
324 main(
int argc,
char **argv)
328 if ( argp.has_arg(
"h") ) {
329 print_usage(argv[0]);
333 std::string command, file;
334 if (argp.num_items() < 1) {
335 printf(
"Invalid number of arguments\n");
336 print_usage(argv[0]);
338 }
else if (argp.num_items() >= 2) {
339 file = argp.items()[1];
342 command = argp.items()[0];
344 if (command ==
"watch") {
345 return watch_file(file);
347 }
else if (command ==
"info") {
348 return print_info(file);
350 }
else if (command ==
"print") {
351 std::vector<const char *> index_strings = argp.items();
352 index_strings.erase(index_strings.begin(), index_strings.begin() + 2);
354 std::vector<unsigned int> indexes(index_strings.size());
355 for (
unsigned int i = 0; i < index_strings.size(); ++i) {
356 long l = atol(index_strings[i]);
357 if (l < 0)
throw Exception(
"Invalid index %li", l);
362 if (indexes.size() == 0) {
363 printf(
"No indexes given.\n\n");
364 print_usage(argv[0]);
368 return print_indexes(file, indexes);
370 }
else if (command ==
"replay") {
371 return replay_file(file);
373 }
else if (command ==
"repair") {
374 return repair_file(file);
376 }
else if ( (command ==
"enable") || (command ==
"disable")) {
377 char *host = strdup(
"localhost");
378 unsigned short int port = 1910;
379 if (argp.has_arg(
"r")) {
380 argp.parse_hostport(
"r", &host, &port);
382 int rv = set_enabled(host, port, (command ==
"enable"));
386 }
else if (command ==
"convert") {
387 if (argp.num_items() != 4) {
388 printf(
"Invalid number of arguments\n");
389 print_usage(argv[0]);
392 std::string outfile = argp.items()[2];
393 std::string format = argp.items()[3];
394 return convert_file(file, outfile, format);
397 printf(
"Invalid command '%s'\n", command.c_str());
398 print_usage(argv[0]);
Interface field iterator.
double in_sec() const
Convet time to seconds.
const char * get_typename() const
Get type of current field as string.
Fawkes library namespace.
Interface for signal handling.
Parse command line arguments.
A class for handling time.
virtual const char * what() const
Get primary string.
Base class for all Fawkes BlackBoard interfaces.
bool has_next()
Check if another entry is available.
void read_next()
Read next entry.
void wait()
Wait (sleep) for this time.
const fawkes::Time & entry_offset() const
Get current entry offset.
SwitchInterface Fawkes BlackBoard Interface.
Base class for exceptions in Fawkes.
void print_info(const char *line_prefix="", FILE *outf=stdout)
Print file meta info.
const char * get_name() const
Get name of current field.
const char * type_id() const
Get type ID.
File Alteration Monitor Listener.
static void repair_file(const char *filename)
Repair file.
bool has_writer() const
Check if there is a writer for the interface.
DisableSwitchMessage Fawkes BlackBoard Interface Message.
void read_index(unsigned int index)
Read entry at particular index.
fawkes::Interface * interface()
Get interface instance.
Monitors files for changes.
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
size_t get_length() const
Get length of current field.
unsigned int remaining_entries()
Get number of remaining entries.
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
void print_trace()
Prints trace to stderr.
EnableSwitchMessage Fawkes BlackBoard Interface Message.
InterfaceFieldIterator fields_end()
Invalid iterator.
static void unregister_handler(int signum)
Unregister a SignalHandler for a signal.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
The BlackBoard abstract class.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Class to easily access bblogger log files.
virtual void close(Interface *interface)=0
Close interface.