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.
Fawkes library namespace.
Interface for signal handling.
Parse command line arguments.
A class for handling time.
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.
bool has_writer() const
Check if there is a writer for the interface.
SwitchInterface Fawkes BlackBoard Interface.
virtual const char * what() const
Get primary string.
Base class for exceptions in Fawkes.
void print_info(const char *line_prefix="", FILE *outf=stdout)
Print file meta info.
const char * type_id() const
Get type ID.
File Alteration Monitor Listener.
static void repair_file(const char *filename)
Repair file.
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.
double in_sec() const
Convet time to seconds.
unsigned int remaining_entries()
Get number of remaining entries.
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
const char * get_name() const
Get name of current field.
size_t get_length() const
Get length of current field.
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.
const fawkes::Time & entry_offset() const
Get current entry offset.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier)=0
Open interface for reading.
const char * get_typename() const
Get type of current field as string.
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.